2D array , row deletion from memory

Started by
8 comments, last by AIRmichael 17 years, 5 months ago
Hey, My program crashes when I try to delete a row from a 2 Dimensional array when I call my "delete row function" for the second time: (0)345908230 (1)212020231 (2)xxxxxxxxx <--- I want to remove this row from memory, (3)ooooooooo <--- after I deleted that one. This is how I do it at the moment (simplified):

//init
int *array = new int*[rows];
array[rows] = new int[colls];


//delete function
void deleterow(int RowtobeDeleted)
{
delete[] array[RowtobeDeleted];
delete[] array;  /* !!! when this line is added, the program crashes when this function is called another time for another row */
}


It might be logical that if "delete[] array" is called for the second time, that it crashes, but how do i delete all the colls of a row then? How do I specify that all colls have to be deleted of only a specific row? Thank you in advance
Advertisement
// Initint *array = new int*[rows];for (int i = 0; i < rows; i++)  array = new int[cols];...// Cleanupfor (int i = 0; i < rows; i++)  delete [] array;delete [] array;


You may want to consider using std::vector< std::vector<int> > though to eliminate possible memory problems.
<a href="http://www.slimcalcs.com>www.slimcalcs.com
Quote:Original post by scottdewald
// Initint *array = new int*[rows];for (int i = 0; i < rows; i++)  array = new int[cols];...// Cleanupfor (int i = 0; i < rows; i++)  delete [] array;delete [] array;


You may want to consider using std::vector< std::vector<int> > though to eliminate possible memory problems.



The initialisation is the same how I have done it, just forgot to post the loop:)

The problem is however, the deletion. The deletion/cleanup is what I would like to do in my function, only for the row I specify with that function, and not all rows. So in theory my function should work right?
Not exactly. Your function deletes a row and then deletes your pointer to the rest of your rows. I am not exactly sure why you would want to simply delete just one row. If you are trying to resize a row, you could do this:
void resizeRow(int **array, int row, int newNumCols){  delete [] array[row];  array[row] = new int[newNumCols];}

That is the only reason why I can think of why you would want to do that. But, if you really just want to delete a row, you could simply omit the second call in my function.
<a href="http://www.slimcalcs.com>www.slimcalcs.com
A good question is: why do you want to delete the row from memory? What do you expect to achieve by doing this? Is there a reason why you do not allocate all rows contiguously in one allocation?
Thanks for the quick reply. The reason that I only want to delete a row, is because of memory. Each row is like 80 mb in ram memory.

I would also like to delete the pointer of that single row by the way. If I delete only the row like you showed in your function (I did it before), and create the row again,delete it again etc, then the memory useage keeps growing. So it seems that not everything is deleted (It only deletes about 20%).
Quote:Original post by AIRmichael
I would also like to delete the pointer of that single row by the way. If I delete only the row like you showed in your function (I did it before), and create the row again,delete it again etc, then the memory useage keeps growing. So it seems that not everything is deleted (It only deletes about 20%).


Your problem is that "memory" is not very liquid in non-garbage-collected languages. The most striking example is as follows: you delete two objects of size sizeof(A) then allocate an object of size 2*sizeof(A), but your memory usage increases instead of staying the same!

The reason for this is that memory becomes fragmented. Even though you deleted your row, it does not automagically return to a fictitious pool of available memory. Rather, it stays where it was, in-between other used or unused blocks of memory, and is marked as "free". Now, if you release an 80-megabyte block, then allocate a 4-byte object, the memory allocator might well use 4 bytes out the 80 to represent your object! And when you try to allocate another 80-megabyte block, but there are only 79.999.996 contiguous bytes available in free memory, and so an entirely new block of 80 megabytes is created.

Although 80 megabytes is a surprisingly large amount — what, exactly, are you stocking in there?

It is in general preferable to pool resources yourself by creating your own allocator: this will prevent other allocations from fragmenting your big blocks, and also makes allocation faster (since you keep a list of free big blocks, you can get one in constant time).

Of course, most mark-and-sweep garbage collectors don't have this problem, since they actually move objects around in memory to reduce fragmentation.
You should NULL out your pointers after you delete them. The memory is gone, so it makes no sense to ask for it anymore, and then you won't crash if you call delete on that row again.

//delete functionvoid deleterow(int RowtobeDeleted){    delete[] array[RowtobeDeleted];    array[RowtobeDeleted] = NULL;}


If you're only deleting one row, then it makes no sense to delete the memory pointed to by array...


Also, I'm a little confused... you said you had an initialization loop like scottdewald wrote up, but your original post had:
//initint *array = new int*[rows];array[rows] = new int[colls]; // You're corrupting memory here. "rows" is not a valid index for array.
The init is actually more like this: ( a per row initialisator )

int allrows = 9;
int *array = new int*[allrows];
void init(int therow)
{
//init
array[therow] = new int[colls];
}


But initialisation is ok. I will now try to delete all the pointers and see if it improves alot more. The reason I reserve like 80 mbs, is that it is a medical application, and lots of genome data has to be loaded. (huge data files).

Greetings, Mic
LOL I think its quite logical this does not work. I am swapping around like half a gig of ram within a second useing a slider in a interface. That is like crazy, swapping around faster then the machine can handle.

This topic is closed to new replies.

Advertisement