memory leaks - C++ Where is the seg fault? -
i tackling assignment computer science class:
make own dynamic array template. should allow creating contiguous arrays (filled things of same type) can extend without worrying running out of space.
do 1 version using malloc , free.
do 1 version using new , delete.
my version using new , delete works flawlessly; however, in trying convert new/delete code using malloc/free, keep getting seg fault. have narrowed down segfault (i think), being in single function: adddata. take @ code in main used test this:
array2<int> *testarray3 = new array2<int>(5); array2<int> *testarray4; testarray3->initarray(); testarray3->printarray(); testarray4 = testarray3->adddata(7); testarray4->printarray(); return 0;
this gives seg fault; however, when change this:
array2<int> *testarray3 = new array2<int>(5); array2<int> *testarray4; testarray3->initarray(); testarray3->printarray(); testarray4 = testarray3; //->adddata(7); testarray4->printarray(); return 0;
there no seg fault. makes me believe issue in adddata function. here code that:
array2<t> *adddata(t datatoadd){ array2 <t> *tmp; tmp->data = this->getdata(); array2 <t> *newdata; newdata->data = (t *) malloc(sizeof(t)*(this->size + 1)); (int = 0; < tmp->getsize() + 1; ++i){ if (i < tmp->getsize()){ //newdata->data[i] = tmp->data[i]; newdata->setdata(tmp->getdata()[i], i); } else{ //newdata->data[i] = datatoadd; newdata->setdata(datatoadd, i); } } free(tmp->data); free(this->data); return newdata; };
i new programming whole , have not wrapped head around pointers , memory allocation, etc. advice give me appreciated! in case need see rest of code, here entire file coded template in. thank time!
#include <iostream> #include <string> #include <cstdlib> #include <sstream> using namespace std; template<typename t> class array2{ public: array2(int size){ this->size = size; data = (t *) malloc(sizeof(t)*size); }; array2<t> *adddata(t datatoadd){ array2 <t> *tmp; tmp->data = this->getdata(); array2 <t> *newdata; newdata->data = (t *) malloc(sizeof(t)*(this->size + 1)); (int = 0; < tmp->getsize() + 1; ++i){ if (i < tmp->getsize()){ //newdata->data[i] = tmp->data[i]; newdata->setdata(tmp->getdata()[i], i); } else{ //newdata->data[i] = datatoadd; newdata->setdata(datatoadd, i); } } free(tmp->data); free(this->data); return newdata; }; ~array2(){ free(this->data); }; void initarray(){ (int = 0; < this->size; ++i){ //this->data[i] = i; this->setdata(i, i); } }; void printarray(){ //ostringstream oss; string answer = ""; (int = 0; < this->size; ++i){ //oss << this->data[i] + " "; cout << this->data[i] << " "; } //answer = oss.str(); cout << answer << endl; }; t* getdata(){ return this->data; } int getsize(){ return this->size; } void setdata(t data, int index){ this->getdata()[index] = data; } private: int size; t* data; };
array2 <t> *tmp;
allocates pointer. not point pointer @ or allocate storage pointer point at. points @ without being explicitly assigned undefined. if lucky, , time, tmp points @ invalid location , program crashes. if unlucky, tmp points @ usable region of program memory , lets write on it, destroying whatever information there.
tmp->data = this->getdata();
attempts access data member @ tmp, fortunately access in invalid memory , program comes halt. has tmp's data pointing @ this's data, , that's dangerous position in. changes 1 happen other because both use same storage. think happen this->data if free tmp->data.
or perhaps i'm wrong , halt here same reason:
array2 <t> *newdata; newdata->data = (t *) malloc(sizeof(t)*(this->size + 1));
both need fixed. tmp doesn't have live long, can make temporary local variable.
array2 <t> tmp;
typically created on stack , destroyed when function ends , tmp goes out of scope.
but not work because array2's constructor requires size can allocate array's storage. need find out how big make it. along lines of:
array2 <t> tmp(this->size + 1);
but frankly don't think need tmp @ all. should able copy datatoadd directly newdata without using tmp intermediary.
newdata going returned caller, needs longer scope. time use new
.
array2 <t> *newdata = new array2 <t>(this->size + 1);
and through magic of constructor... wait sec. can't use new
. makes hard. malloc
doesn't call constructors, while malloc
allocate resources newdata, doesn't grunt work set newdata properly. rule of thumb never malloc
object. there exceptions i'm sure, shouldn't asked this. recommend using new
here , politely telling instructor on crack if complain.
anyway, new array2 <t>(this->size + 1)
allocate data
storage it's constructor.
there easier way next bit
for (int = 0; < tmp->getsize() + 1; ++i){ if (i < tmp->getsize()){ //newdata->data[i] = tmp->data[i]; newdata->setdata(tmp->getdata()[i], i); } else{ //newdata->data[i] = datatoadd; newdata->setdata(datatoadd, i); } }
try:
for (int = 0; < tmp->size; ++i){ newdata->data[i] = tmp->data[i]; // right here } newdata->data[tmp->size] = datatoadd;
and hinted @ earlier:
free(tmp->data); free(this->data);
both tmp->data
, this->data
point same memory. honest i'm not sure happens if free same memory twice, doubt it's good. regardless, don't think want free it. leave this
in broken state.
recap , fixes
array2<t> *adddata(t datatoadd) { array2 <t> *newdata = new array2 <t>(this->size + 1); (int = 0; < this->size; ++i) { newdata->data[i] = this->data[i]; } newdata->data[this->size] = datatoadd; return newdata; };
this version leaves intact , returns newdata 1 bigger this. doesn't add this. goofy method named adddata.
it leads stuff this:
mydata = mydata->adddata(data);
which leaks memory. original mydata lost without deletion, resulting in memory leak.
what think need lot simpler:
array2<t> & adddata(t datatoadd) { this->data = realloc(this->data, this->size + 1); this->data[this->size] = datatoadd; this->size++; return *this; };
realloc allocates new buffer, copies old buffer new one, , frees old buffer in 1 fell swoop. groovy.
we add new element , increment count of elements stored.
finally return reference object can used in chain.
usage can be
mydata.adddata(data); mydata.adddata(data).adddata(moredata); mydata.adddata(data).printarray();
and if have operator << support written
std::cout << mydata.adddata(data) << std::endl;
i'd go on new
version of array if you. of bugs picked off here conceptual errors , apply it. might getting unlucky , merely looks works. read c++ calling template function error. posted solutions fixed immediate problem, did not touch underlying memory management problems.
as rest of class, advice following link , answering what rule of three? because array2 violates heck out of it.
Comments
Post a Comment