PDA

View Full Version : FREEING MEMORY! delete [] ....



sandrew
01-15-2002, 06:04 AM
ok! please dont laugh when u read my question!
I am new to programming!

I am trying to delete memory but I am not sure how!

Example:

unsigned char *bitmapImage; // bitmap image data
unsigned char *heightmapData; // the map image data

unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
// allocate memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
..etc...
return bitmapImage;
}

// NOW SEE HERE BELOW!!
void init()
{
heightmapData = LoadBitmapFile("heightmap/terrain.bmp", &bitmap1InfoHeader);

// deallocate memory
free(bitmapImage) // IS IT RIGHT! I DONT NEED IT ANYMORE, SO CAN I DELETE IT THIS WAY?

}

Now for example if I dont need the ==>> heightmapData storage <<== too then how do I delete it? Note I am not using new or malloc see its declaration at the top!!!!
should I use a simple for loop and set all to 0 or there is another way in C++! Actually setting an array to 0 means that we deallocate memory or not?

Could I still use delete [] heightmapData even if I did not use the new operator? is it correct?
How do I free memory currently reserved by the heightmapData array?
Thanks for help!


[This message has been edited by sandrew (edited 01-15-2002).]

mikael_aronsson
01-15-2002, 07:22 AM
Hi !

Setting memory to zero does not free it.

Memory allocated with malloc() must be deleted with free() when no longer needed, memory allocated with new must be deleted with delete.

In your case you need to know how the memory is allocated in the function before you can delete it, most of the time you have a function for doing it, for example if you have a CreateSomething() function that returns a pointer to an allocated memory area you normally have a DeleteSomething() function to use when you don't need the memory any more.

I hope that help's a bit, if you have not created the function that allocated memory yourself then you need to either look at the source code how it is allocated (if you have it) or look for a function that takes care of the deleting.

Just rember the basic rule malloc<->free new<->delete.

Mikael

endo
01-15-2002, 07:28 AM
My experience of C functions is strictly limited, so I am not 100% sure of the answer. One thing I wll say is try not to confuse the different ways of dynamically allocating memory, for example:

int *ptr = new int;
delete ptr;

or this:

int *arrayPtr = new int[ 10 ];
delete[ ] arrayPtr;

this is the C++ method no malloc's, free's, etc - dead simple.

The C method is more complex and I'd be interested to know the answer as well http://www.opengl.org/discussion_boards/ubb/smile.gif

Nutty
01-15-2002, 09:19 AM
Get rid of your global variables!! You only need 1!





unsigned char *heightmapData; // the map image data

unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
//Delcare a temp pointer.
unsigned char *bitmapImage;

// allocate memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
..etc...
return bitmapImage;
}

// NOW SEE HERE BELOW!!
void init()
{
heightmapData = LoadBitmapFile("heightmap/terrain.bmp", &amp;bitmap1InfoHeader);

// deallocate memory
//free(bitmapImage) // IS IT RIGHT! I DONT NEED IT ANYMORE, SO CAN I DELETE IT THIS WAY?

NO THAT IS NOT RIGHT!
In your example bitmapImage, and heightmap both point to the same data. Deleting bitmapImage, will make the contents of what heightmap points to undefined, and quite probably overwritten at some point.

Only free heightmap pointer when you're finished with the heightmap data! Getting the address of the bitmap as a local, prevents you from accessing that variable outside it's scope anyway.

}

sandrew
01-15-2002, 12:42 PM
Thanks Guys!!
-----------------------------------------------------------------------------------------
Deleting bitmapImage, will make the contents of what heightmap points to undefined, and quite probably overwritten at some point.
-----------------------------------------------------------------------------------------
NUTTY!! You're right!! I never thought about it!!
so, the heightmapData must be freed first then I can free bitmapImage whenever I wish!

But just 2 more questions!
1.
I am not allocating any memory for ==> heightmapData <== by using malloc or delete. Thats all you can see in the code above, so do you think that I could delete/free the heightmapData array by using delete [] or free()
eg. delete [] heightmapData; //is it ok?
even though I haven't used new/malloc beforehand? just like I did above in the code for bitmapImage array for which is allocated memory by using malloc. will it be ok!! will it destroy the heightmapData array?

2. I could never understand if I for example declare a variable
int/char/float array[1000];
then fill it in with some data by using a for() loop and then terminate the program with exit(0);. Now. Do I have to worry about memory deallocation or its done for me automatically?


Oo yeah! Someone has suggested that when using eg.
free (bitmapImage);
it is good to add one more line below which is the following
bitmapImage=NULL;



[This message has been edited by sandrew (edited 01-15-2002).]

Nutty
01-15-2002, 01:02 PM
where is the code for LoadBitmapFile?

If its a pre-compiled library, is it a C, or C++ library? IF it's C, then you should be able to use Free, or if it's a C++ library use delete.

You dont need to use delete[] unless you have an array of class instances.

Nutty

sandrew
01-15-2002, 01:14 PM
NUTTY!! this is the code for LoadBitmapFile:
PS.
I am writing everything in C++ but the BMP loader is written in C so I guess I will have to convert it to C++ which I am not 100% what needs to be changed apart form malloc/free()?
do u think that I should look for another BMP loader already written in C++ or I should try to modify this loader. Actually is there anything wrong if I use bits of C code within C++ code. it still compiles ok!
Do you also think that this code will work fine on LINUX???

/************************************************** *********************************
* LoadBitmapFile *
* desc: Returns a pointer to the bitmap image of the bitmap specified *
* by filename. Also returns the bitmap header information. *
* No support for 8-bit bitmaps. *
************************************************** *********************************/
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
FILE *filePtr; // the file pointer
BITMAPFILEHEADER bitmapFileHeader; // bitmap file header
//unsigned char *bitmapImage; // bitmap image data
unsigned char tempRGB; // swap variable
unsigned int imageIdx = 0; // image index counter

// open filename in "read binary" mode
filePtr = fopen(filename, "rb");
if (filePtr == NULL)
return NULL; //nothing read

// read the bitmap file header
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);

// verify that this is a bitmap by checking for the universal bitmap id
if (bitmapFileHeader.bfType != BITMAP_ID)
{
fclose(filePtr);
return NULL;
}

// read the bitmap information header
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);

// move file pointer to beginning of bitmap data
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);

// allocate enough memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);

// verify memory allocation
if (!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
return NULL;
}

// read in the bitmap image data
fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);

// make sure bitmap image data was read
if (bitmapImage == NULL)
{
fclose(filePtr);
return NULL;
}

// swap the R and B values to get RGB since the bitmap color format is in BGR
for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}

// close the file and return the bitmap image data
fclose(filePtr);
return bitmapImage;
}

then the rest is at the top of this page!


[This message has been edited by sandrew (edited 01-15-2002).]

[This message has been edited by sandrew (edited 01-15-2002).]

[This message has been edited by sandrew (edited 01-15-2002).]

Nutty
01-15-2002, 02:02 PM
Well if you wanted to know weather to use free or delete...




// allocate enough memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);


It uses malloc, so use free, to de-allocate the heightmap data when you're done.

I have no idea if it will compile under linux, I dont have linux. Prodided theres no reference to any OS dependant features, then most should be easily portable.

Nutty

sandrew
01-15-2002, 02:12 PM
ok! thanks for your advice!!
I did use free() to dealocate memory for bitmapImage array
but... I still did not get any answer about the heightmapData array for which I am not allocating memory by using malloc or new!! How do I delete this array? should I use free/delete or no need to do it?
Sorry but I want to make sure!
Thanks again!! http://www.opengl.org/discussion_boards/ubb/smile.gif


[This message has been edited by sandrew (edited 01-15-2002).]

[This message has been edited by sandrew (edited 01-15-2002).]

Nutty
01-15-2002, 02:25 PM
heightmapDat and bitmapImage Point to the same address!

If you delete one, the other will get deleted automatically.

You shouldn't use a global pointer for loading in images. Use a local pointer like in the code I posted, and return that.

Then all you have to worry about is freeing heightmapData. By using free().

The memory it points to was allocated using malloc. Just because you stored this in a different pointer, doesn't mean anything. It's the address of the actual memory you allocated that is important, and you stored this address in both bitmapImage _AND_ heightmapData.

You only need to free 1 of them. As they are pointing to the same piece of memory.

Nutty

Selva
01-15-2002, 03:24 PM
Hi Sandrew,

I think your problem is the understanding of
array in C. In C array not an object. It is
just a chunk of memory.

So
char *ptrA, *ptrB;
...
ptrA = ptrB;

does not mean the array pointed by ptrB is
copied to ptrA. Simply both will point to
the same array. If you modify thru either
variable, both will reflect the change.

In your case you malloc 'bitmapImage' and
assign it to 'heightmapData' (by returning
from the function). So both point to the
same memory. If you free EITHER one, both
become meaningless, though they still point
to SOME PART OF THE MEMORY.

Reading about arrays in C will help to get a
better understanding.


[This message has been edited by Selva (edited 01-15-2002).]

lobstah
01-16-2002, 03:59 AM
Whenever you use malloc, you must free(it)!

Also, especially for Windows, after freeing, you should set the pointer to null.

This is a practice of C programing.

Also, if you use arrays (an array declaration) the OS will clean up for you. However, if you have an array of pointers, you must free what the pointer is pointing to prior to the program, dll, etc terminating.

Hope this helps.

sandrew
01-16-2002, 04:01 AM
OK!!! Now I understand!! I will also change the global to a local variable for that bmp loader function!
THANK YOU VERY MUCH Nutty, Selva and others!! You helped me a lot!!!! http://www.opengl.org/discussion_boards/ubb/smile.gif

Last question!! would it be ok if I set the heightmapData to NULL just one line below after freeing the memory. (see below)

free(heightmapData);
heightmapData = NULL; // <-- is it ok? or not needed?

[This message has been edited by sandrew (edited 01-16-2002).]

lobstah
01-16-2002, 04:08 AM
Yes, this is a good practice.

Another way to look at it is:
I just release resources back to the OS (free), so now what is my pointer pointing to? You don't know, so set it to NULL to indicate nothing, so you do know.

lobstah...

sandrew
01-16-2002, 09:05 AM
Ok! Thanks all for help!!
Now everything is much clearer for me!! http://www.opengl.org/discussion_boards/ubb/smile.gif