template <class T> class Signal {
protected: int N; // length of array
public: T *sig;
Signal<T> fft();
}
template <class T> Signal<T> Signal<T>::fft() {
if (N==1) return *this;
if (N%2!=0)
cout<<"N is not power of 2";
else{
Signal<T> even;
even.sig=new T[N/2];
Signal<T> odd;
Signal<T> esig;
Signal<T> osig;
Signal<T> y;
y.sig=new T[N];
for (int i=0;i<N/2;i++) {
even.sig[i]=sig[2*i]; /* I failed here because new operator allocate array with negative value*/
}
esig= even.fft();
odd = even;
for (int i=0;i<N/2;i++) {
odd.sig[i]=sig[2*i+1];
}
osig= odd.fft();
/*not importan part*/
}
return y;
}
This is part of my class which represent Signal. I show only one one part of method fft which failed.
I got error Invalide allocation size 4294967295 in line where I put comment. When I debug I got that value for even.sig is 0x0062b9f8 {-842150451}.
How can I fix this and got array of not negative size.
Related
I'm creating a generic box with a template. Basically something like a queue or linked list. I keep getting a SIGSEGV for some reason and I can't figure it out. I take in an integer or a string from the user in main and then the constructor makes allocates memory for the generic box to exist, then using function inert_First (there are a lot more functions like insert_Mid, insert_last, delete_Mid etc) and it keeps telling me I'm accessing wrong memory but I don't know where ?
this is the class
template<class T>
class g_Box
{
int first,mid,last;
int no_Of_Ele;
int capacity;
T *ele;
public:
g_Box();
g_Box(int);
void insert_First(T);
};
this is the constructor
template<class T>
g_Box<T>::g_Box(){
first=-1, last=-1, mid=-1;
no_Of_Ele=0;
capacity=10;
T *ele = new T[capacity];
}
template<class T>
g_Box<T>::g_Box(int a){
first=-1, last=-1, mid=-1;
no_Of_Ele=0;
capacity=a;
T *ele = new T[capacity];
}
This is the insert_First
template<class T>
void g_Box<T>::insert_First(T a){
if(isFull()){
cout<<"The box is full";
}
else if(isEmpty()){
first=0; last=0; mid=(first+last)/2;
ele[0]=a;
no_Of_Ele++;
}
else{
T *ele2 = new T[capacity];
//T ele2[capacity];
for(int i=0; i<no_Of_Ele; i++){
ele2[i]=ele[i];
}
for(int i=0; i<no_Of_Ele; i++){
ele[i+1]=ele2[i];
}
ele[first]=a;
last++;
mid=(first+last)/2;
no_Of_Ele++;
delete[] ele2;
}
}
and this is the main
int main()
{
g_Box<int> g;
int data;
cin>>data
g.insert_First(data);
}
What I'm trying to create is a TestScore Template class that just simply calculates the average of a array. I'm trying to throw a exception when a grade is negative or bigger than 100. I have created a NegativeScore exception class and a TooLargeScore exception class,both which just return a string message. In main, i create my array and ask the user for the grades, then use the class to get the average but for some reason it doesnt find the average. It doesnt print out the average when i try to. Im thinking the problem lies with my pointers but i dont know what the exact problem is, anyone know?
#ifndef TESTSCORES_H_INCLUDED
#define TESTSCORES_H_INCLUDED
#include <iostream>
#include "NegativeScore.h"
#include "TooLargeScore.h"
#include <iomanip>
using namespace std;
template <class T>
class TestScores
{
private:
T* testscores[];
public:
TestScores(T testscores[]);
T GetAverage();
};
template <class T>
TestScores<T>::TestScores(T testscores[])
{
*(this->testscores) = testscores;
}
template <class T>
T TestScores<T>::GetAverage()
{
T average;
T sum;
T counter;
for(int i = 0; i <= 5; i++)
{
if(*testscores[i] < 0)
{
throw NegativeScore("Test Score is negative, its invalid!");
}
else if(*testscores[i] > 100)
{
throw TooLargeScore("Test score it too high, its invalid!");
}
else
{
sum = sum + *testscores[i];
}
counter++;
}
average = sum / 5;
return average;
}
MAIN
int main()
{
int MAX = 5;
double scores[MAX];
for(int i = 0; i < MAX; i++)
{
int score;
cout << "Enter the test score for test "<< (i+1) << endl;
cin >> score;
scores[i] = score;
}
try
{
TestScores<double> tests(scores);
tests.GetAverage();
cout << tests.GetAverage() << endl;
}
catch(NegativeScore ex)
{
cout << ex.getMessage() << endl;
}
catch(TooLargeScore ex2)
{
cout << ex2.getMessage() << endl;
}
return 0;
}
Your problem is that you class holds an array of pointer to T, but you attempt to initialize it with a array of double (i.e. array of T values).
template <class T>
class TestScores
{
private:
T* testscores[];
public:
TestScores(T testscores[]);
T GetAverage();
};
template <class T>
TestScores<T>::TestScores(T testscores[])
{
*(this->testscores) = testscores; // <--- This is not doing what you think it is.
}
I am surprised that compiled, and you should strongly consider using a better compiler that will warn you of dubious operations.
You should change the class to hold a plain pointer-to-T, i.e. a T* testscores;, or better, an std::vector<T>.
For example, I could get your code working with this change:
template <class T>
class TestScores
{
private:
T* testscores; // Note simpler pointer to first element of array of length of 5.
public:
TestScores(T testscores[]);
T GetAverage();
};
You also have an error in the limits of your for loop in GetAverage (should not include 5), and your variables in that function are uninitialized and may hold garbage values.
I'm trying to overload the addition operator but I keep getting a segmentation fault even though I'm passing in the argument by value after it's memory has been deallocated. Anybody have any idea what I could be doing wrong. Also once I get this running properly after fixing the overloaded addition, I need to use vectors instead of pointing to arrays which I have no idea how to declare in a manner equivalent to what I've wrritten for arrays.
RowAray.h
#ifndef ROWARAY_H // if constant ROWARAY_H not defined do not execute
#define ROWARAY_H // defines constant ROWARAY_H
#include <new> // Needed for bad_alloc exception
#include <cstdlib> // Needed for the exit function
template <class T>
class RowAray{
private:
int size;
T *rowData;
void memError(); // Handles memory allocation errors
void subError(); // Handles subscripts out of range
public:
RowAray(T); //used to construct row Array object
~RowAray(){delete [] rowData;} //used to deallocate dynamically allocated memory from Row array
int getSize(){return size;} //inline accessor member function used to return length of Row array
void setData(int row, T value);
T getData(int i){return (( i >=0&& i < size)?rowData[i]:0);} //
T &operator[](const int &);
};
template <class T>
RowAray<T>::RowAray(T colSize){
size =colSize>1?colSize:1;
// Allocate memory for the array.
try
{
rowData = new T [size];
}
catch (bad_alloc)
{
memError();
}
// Initialize the array.
for (int count = 0; count < size; count++){
T value = rand()%90+10;
setData(count, value);
}
}
template <class T>
void RowAray<T>::memError()
{
cout << "ERROR:Cannot allocate memory.\n";
exit(EXIT_FAILURE);
}
template <class T>
void RowAray<T>::subError()
{
cout << "ERROR: Subscript out of range.\n";
exit(EXIT_FAILURE);
}
template <class T>
T &RowAray<T>::operator[](const int &sub)
{
if (sub < 0 || sub >= size)
subError();
else
return rowData[sub];
}
template <class T>
void RowAray<T>::setData(int row, T value){
//used to fill array with random 2 digit #s
*(rowData + row) = value;
}
#endif /* ROWARAY_H */
Table.h
#ifndef TABLE_H
#define TABLE_H
#include "RowAray.h"
template <class T>
class Table{
private:
int szRow;
int szCol;
RowAray<T> **records;
public:
Table(int,int); //used to construct Table object
Table(const Table &);
~Table(); //used to deallocate dynamically allocated memory from Table object
int getSzRow() const{return szRow;} //used to return row size
int getSzCol()const {return szCol;}
Table operator+(const Table &);
T getRec(int, int) const; //used to return inserted random numbers of 2d arrays
};
template <class T>
Table<T>::Table(int r, int c ){
//Set the row size
this->szRow = r;
//Declare the record array
records = new RowAray<T>*[this->szRow];
//Size each row
this->szCol = c;
//Create the record arrays
for(int i=0;i<this->szRow;i++){
records[i]=new RowAray<T>(this->szCol);
}
}
template <class T>
Table<T>::Table(const Table &Tab){
szRow=Tab.getSzRow();
szCol=Tab.getSzCol();
records = new RowAray<T>*[szCol];
for(int i = 0; i < this->szCol; i++){
records[i] = new RowAray<T>(szRow);
}
//set elements = to random value
for(int row = 0; row < szRow; row++){
for(int col = 0; col < this->szCol; col++){
int value = Tab.getRec(row, col);
records[col]->setData(row,value);
}
}
}
template <class T>
T Table<T>::getRec(int row, int col) const{
//if else statement used to return randomly generated numbers of array
if(row >= 0 && row < this->szRow && col >= 0 && col < this->szCol){
return records[row]->getData(row);
}else{
return 0;
}
}
template <class T>
Table<T>::~Table(){
//Delete each record
for(int i=0;i<this->szRow;i++){
delete records[i];
}
delete []records;
}
template <class T>
Table<T> Table<T>::operator+(const Table &Tab){
Table temp(Tab.getSzRow(), Tab.getSzCol());
//set elements = to random value for operation to
for(int row=0; row < szRow; row++){
for(int col=0; col < szCol; col++){
int value = getRec(row, col) + Tab.getRec(row, col);
temp.records[col]->setData(row,value);
}
}
return temp;
}
#endif /* TABLE_H */
main.cpp
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
using namespace std;
//User Libraries
#include "Table.h"
//Global Constants
//Function Prototype
template<class T>
void prntRow(T *,int);
template<class T>
void prntTab(const Table<T> &);
//Execution Begins Here!
int main(int argc, char** argv) {
//Initialize the random seed
srand(static_cast<unsigned int>(time(0)));
//Declare Variables
int rows=3,cols=4;
//Test out the Row with integers and floats
RowAray<int> a(3);
RowAray<float> b(4);
cout<<"Test the Integer Row "<<endl;
prntRow(&a,3);
cout<<"Test the Float Row "<<endl;
prntRow(&b,4);
//Test out the Table with a float
Table<float> tab1(rows,cols);
Table<float> tab2(tab1);
Table<float> tab3 = tab1 + tab2;
cout<<"Float Table 3 size is [row,col] = Table 1 + Table 2 ["
<<rows<<","<<cols<<"]";
prntTab(tab3);
//Exit Stage Right
return 0;
}
template<class T>
void prntRow(T *a,int perLine){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int i=0;i<a->getSize();i++){
cout<<a->getData(i)<<" ";
if(i%perLine==(perLine-1))cout<<endl;
}
cout<<endl;
}
template<class T>
void prntTab(const Table<T> &a){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int row=0;row<a.getSzRow();row++){
for(int col=0;col<a.getSzCol();col++){
cout<<setw(8)<<a.getRec(row,col);
}
cout<<endl;
}
cout<<endl;
}
You error stems from line 85 of Table.h, in you + operator overload:
temp.records[col]->setData(row,value);
should really be
temp.records[row]->setData(col,value);
Apart from that, I spotted another error in the same file in line 62 (method Table<T>::getRec(int row, int col)):
return records[row]->getData(row);
should be
return records[row]->getData(col);
Apart from those problems, I would highly advise you to rethink and restructure your code (maybe you could also try a code review), since a large part of it is superfluous in my opinion and some things could become problematic if you expand the project (for example, RowAray's constructor takes a T colSize as parameter where you should probably use an int or, better, a size_t. This code as it is will not work when T is not implicitly convertible to an integer type).
I'm learning C++, and we were given an exercise to make a stack class using a class template and pointers. I'm not yet fully understanding the implementation of a stack or pointers so I gave it a go and made this class:
template <class T>
class Stack_Class {
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value) {
if (value > 0) {
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class() {
if (First_item) {
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num) {
if (item_quantity <Max_quantity) {
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop() {
if (!Empty()) {
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty() {
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity() {
return Max_quantity;
}
And the main class would be:
#include <iostream>
#include "Stack_Class.h"
void main() {
Stack_Class<int> intStack(3);
intStack.Add(1);
intStack.Add(2);
intStack.Add(3);
int count = intStack.GetMax_Quantity();
for (int i = 0; i < count; i++) {
std::cout << "Pop No: " << i << " - Elemento: " << intStack.Pop() << std::endl;
}
}
Though as a result I'm getting all random numbers instead of the ones I gave it in intStack. Add, so my question would be I'm implementing the pointer correctly here?
You need to deincrement the stack pointer before you reference it within Pop():
template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
stack--;
return *stack;
}
return NULL;
}
Your array access stack[item_quantity] does not work because you increment stack in Add. So after construction, the memory pointed to by stack looks like this
0xff65f96f <-- *(stack + 0)
0x0eec604f <-- *(stack + 1)
0x05be0582 <-- *(stack + 2)
0x29b9186e <-- *(stack + 3)
The hexdecimal values represent random garbage coincidentely located in the memory at the time of allocation. This is because memory allocated by new is not initialized to something nice. After adding three values, it looks like this
1 <-- *(stack - 3)
2 <-- *(stack - 2)
3 <-- *(stack - 1)
0x29b9186e <-- *(stack + 0)
0xf66eff06 <-- *(stack + 1)
0x357eb508 <-- *(stack + 2)
In the first call of Pop, you access stack[2] = *(stack + 2), because item_quantity is 2 after deincrementing it. The two consecutive calls to Pop access stack[1] and stack[0]. As you can see above, you never actually reference the values you’ve put into the stack.
You are mixing up the pointer incrementing semantic in the Add method and the indexing semantic in the Pop method.
Since you need the index for the Empty method and so on, I would fix your Add method instead of the Pop as can be seen below.
Otherwise, you would end up still using the indexing in some method(s), but not in other. It would not look consistent to me.
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
stack[item_quantity++] = num;
return true;
}
else return false;
}
Yet another problem in your code is this:
stack = new T[value];
but you seem to only delete the first element in the pointer. That is a guaranteed (and potentially not negligible) memory leak.
Even if you fix all that, your code would not still compile since you are trying to return void, whereas a C++ program should return int, so change this:
void main(){
...
}
to:
int main(){
...
}
... and return an integer like 0 correspondingly.
You would also need to fix this warning:
Stack_Class.h:56:13: warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null]
return NULL;
^
By for instance change NULL to 0.
Having fixed all that, the output is like this:
Pop No: 0 - Elemento: 3
Pop No: 1 - Elemento: 2
Pop No: 2 - Elemento: 1
You can also see the code running on ideone.
For your convenience, this is the whole working code after those fixes:
template <class T>
class Stack_Class{
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value){
if (value > 0){
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class(){
if (First_item){
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty(){
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity(){
return Max_quantity;
}
I declared the size of the array to be 2 and I tried inserting on the 3rd array position. The insert function is supposed to throw -1 when the position > size+1(using pos-1 when assigning the element into the array) but the throw is not stopping the assignment for the 3rd array position so I am getting a segmentation fault.
template <class T, int N>
class person : public people<T>
{
private:
T a[N];
int size;
public:
person();
virtual void insert(int pos, T info);
virtual T show(int pos);
};
template<class T, int N>
person<T,N>::person(){
size = 0;
}
template <class T, int N>
void person<T,N>::insert(int pos, T info){
if (pos <= 0 || pos > size+1)
throw -1;
a[pos-1] = info;
++size;
}
template <class T, int N>
T person<T,N>::show(int pos){
if ( pos <= 0 || pos > size+1 )
throw -1;
return a[pos-1];
}
void putin( people<name>*& aPerson ) {//passing aPerson itself
string first("Julia"), last("Robert");
name temp(first, last);
string ft("Delilah"), lt("McLuvin");
name temp2(ft, lt);
string fst("oooh lala"), lst("broomdat");
name temp3(fst, lst);
try{
aPerson-> insert(1,temp);
aPerson-> insert(2,temp2);
aPerson-> insert(3,temp3);
}
catch(...){ cout<< "error\n";}
}
int main(){
people<name>* aPerson = new person<name, 2>();
putin(aPerson);
try{
cout << aPerson->show(1);
cout << aPerson->show(2);
cout << aPerson->show(3);
}
catch(...){ cout<< "error\n";}
return 0;
}
Every time you insert something, you check size variable and later increment it. When you hit size == N, nothing happens. You just step out of array bounds, you need to consider case when size is about to get bigger than your array.
Are you using STL? If yes better try using vector<T>::at secure method which will do all necessary checks for you and throw std::out_of_range exception when getting outside its bounds.