0

Having some trouble deleting a dynamically allocated array, and I'm not 100% sure why. The only thing I do to this array is copy over some values from it individually (in a for loop), in another routine, which is verified to work correctly.

Here is the declaration in class:

std::complex<float> * frameData;

instantiation in constructor:

this->frameData = new std::complex<float>[n];
srand( time(NULL) );
std::complex<float> randUnityRoot;

for( int i = 0; i < this->n; i++){
    randUnityRoot = std::polar(1.0, 2*M_PI * (rand() % 1000000)/1e06);
    this->frameData[i] = randUnityRoot;
}

deletion in destructor(this is the line 70 mentioned in the backtrace):

delete[] this->frameData;

gdb backtrace after segfault at program completion:

(gdb) f 4
#4  0x00007ffff7bc579c in Frame::~Frame (this=0x602940, 
__in_chrg=<optimized out>) at Frame.cpp:70 
70      delete[] this->frameData;
(gdb) f 3
#3  0x00007ffff7669b96 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) f 2
#2  0x00007ffff765f39e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) f 1
#1  0x00007ffff7624b8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) f 0
#0  0x00007ffff7621425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) 

I've been staring at this for a while and am right out of ideas. I figured I would turn to the hive mind. Please let me know if you would like any more information. Thanks!

EDIT: I updated everything to a vector and vector* based approach.

No segfaults :).

To generate some sort of "knowledge gained" from this however, in another class I had called something like:

std::complex<float> * frameGet;
frameGet = this->Frame->getFrame();
// Do stuff with frameGet
//THIS NEXT LINE IS THE BAD PART
delete[] frameGet;

Half question, half assertion: delete[] frameGet calls delete on original array content? If frameGet needs to be deleted should do something like:

frameGet = NULL;
delete frameGet;
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Steve Novakov
  • 193
  • 3
  • 12

1 Answers1

0

You most probably do not have either copy-ctor nor assignment operator explicitly defined in your class. So describe them in private section of your class (make then inaccessible):

class Frame {
//...
private:
   Frame( const Frame & );
   Frame &operator=( const Frame & );
// ...
};

you do not even have to implement them and compiler will show exact locations where your problem is by compilation errors.

About second half of your question. For some reason you think if you assign one raw pointer to another you copy that memory and need to delete them separately. That not the case, raw pointer is just a number - address in memory. So:

int *pi = new int[N]; // now pi has address of memory reserved by new, lets say 0x1234
int *api = pi;  // now api has the same address 0x1234 as pi
delete[] api; // you tell environment that you do not need memory at address 0x1234 anymore
delete[] pi; // you tell environment that you do not need memory at address 0x1234 again, which is error

The fact you just assign one pointer to another directly or do that through function result or parameter pass does not change anything.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • Well, why would I need the copy constructor when I never do anything with that array other than access individual variable elements a la **float something = this->frameData[i].re() + 3** – Steve Novakov Mar 01 '13 at 05:40
  • @Steve The point is we don't *really* believe that you're not silently copying somewhere ;-) . Making copy ctor and copy assignment inaccessible and recompiling will prove beyond any doubt that this is not what's happening. – us2012 Mar 01 '13 at 05:43
  • @SteveStevens put 2 lines into your code and compile will not take too long, why not to try before asking why would you need it? – Slava Mar 01 '13 at 05:45
  • @us2012 unless one of the member function of Frame itself does that copy or assignment. – Slava Mar 01 '13 at 05:48
  • @Slava, Us2012. The comments to my question made the very valid point that I could use a vector here, which I totally can and am doing : ) I'm currently changing all my code to use vectors for that and another dynamically allocated array in the same class. I will try this though with the old revision. Thanks. – Steve Novakov Mar 01 '13 at 05:49
  • so is there potential for silent copy in fetching it from another class via member function? I do have a std::complex * frameGet; frameGet = this->frameList->getFrameData(); In another class. – Steve Novakov Mar 01 '13 at 05:51
  • std::vector<> or using smart pointer will definatly solve the issue if it is because you are silently copying. – Slava Mar 01 '13 at 05:52
  • @SteveStevens it depends what you are doing with that frameGet afterwards – Slava Mar 01 '13 at 05:53
  • I should mention that getFrameData() executes the following: return this->frameData; It was my belief that this simply returns the ptr address – Steve Novakov Mar 01 '13 at 05:54
  • what I'm doing with the frameGet? well that is complicated lol: 1) copying select pieces of it into several new dynamically allocated pointer arrays of type float (remember that this is type complex, I'm using the real(), imag() methods) 2) sending those pieces into openCL memory buffers and executing math on them in GPU's 3) fetching that from GPU's I still do not see any potential for silent copy, but I said I would try the above and I will! Just not now ; ) – Steve Novakov Mar 01 '13 at 05:56
  • @SteveStevens I am not asking what you are doing with that data it points to. What are you doing with pointer itself? Do you call delete[] on it? Do you keep it as a member variable and later call delete[] by dtor? – Slava Mar 01 '13 at 05:58
  • yes, I call delete[] on frameGet. Hmmmm. I think I can see how that could be a problem. – Steve Novakov Mar 01 '13 at 06:35
  • @SteveStevens you delete the same pointer twice, that indeed could be a problem – Slava Mar 01 '13 at 06:39
  • Yeah, Updated my post, I think this is problem solved. TYVM. Sometimes it just takes a second pair of eyes ; ) – Steve Novakov Mar 01 '13 at 06:40