Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

char* myArray[] and memory managment

This topic is 5580 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Howdy folks, I''m having a hard time understanding the nature of c-strings (and memory management). It seems to me that if i assign a cell of my char* array to a c string I ought to have to free the memory by eg: myArray[1] = "new string"; delete [] myArray[1]; clearly this isnt the case because it crashes. Isnt a c string stored on the heap? I''m totally confused. thanks, dave

Share this post


Link to post
Share on other sites
Advertisement
Wow. Several things wrong here. Let''s take it a half-line at a time...

myArray[1]

First of all, of what type is myArray, and where is it declared?

For purposes of discussion, I''ll assume it''s a char pointer array (it could be a char array, but that seems less likely to me).

Now, myArray[1] is a single element in this char*array, which means that it CAN "store" a string, but first it has to have memory allocated to it. For example:

myArray[1] = new char[32]; // "makes room" for 32 chars;

The second false assumption you make is that it''s possible to assign one char pointer to another directly, and that a deep copy will occur. This is false. You must explicitly copy the data using a function like strcpy. For example:

strcpy(myArray[1], "new string");

The only way you could actually do an assignment in the way you have would be in an initializer.

Your final statement is correct. To delete the memory we allocated to (char *)myArray[1], we say

delete [] myArray[1];

Now, all this has been based on the assumption that myArray is indeed a char pointer array, and not a char array. If it is declared as a char array, just let us know so someone can explain what''s wrong there.

Peace,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

Share this post


Link to post
Share on other sites
Hmm, that''s interesting. This leads me to believe that "quoted" string data is held somewhere (at the beginning?) on the stack. I''m assuming that myArray is on the heap of course. This could lead to some very nasty problems (e.g. not knowing whether you have a string created from a file or from quotes). To avoid these problems, the assignment would have to be different when used on a pointer than when used on a char array. Come on programing gurus, is that the case?

______________________________

And the Phoenix shall rise from the ashes...

--Thunder_Hawk -- ¦þ
______________________________

Share this post


Link to post
Share on other sites
Ok, I better clarify a little. I''ll show a better abstraction of what I''m doing.

I have a class with a private member:
char* messageQueue[10];

and the method
void addMessage(char * message);
a gross simplification of this method would be:
{
messageQueue[numMessages] = message;
}
I don''t think i need to use strcpy() like zelixir said because a for my intended purpose a shallow copy is sufficient(correct me if im wrong, i will just use this function like addMessage("my message")).

but now say that i want to point that same memory cell to a new c string. if i simply say messageQueue[sameCell] = "test" will that cause a memory leak? I''ve tried to do this first, delete [] messageQueue[sameCell], and it causes the program to crash. Hopefully this further explanation will help reveal what i am not understanding.

also zelixir (thanks for the helpful reply),
I do not understand why you say i cannot simply point one of my char pointers to another string pointer. Doesn''t the pointer just represent the beginning of that strings address?


thanks all,
dave



Share this post


Link to post
Share on other sites
It all depends on how the message strings are stored in memory. This depends on how they''re declared.

Take the following example.

void GenerateMessage()
{
char aMessage[] = "ATTACK GRUGNOR 15";
addMessage(aMessage);
}

K. Now, whenever anyone tries to access that particular message, they get a pointer that doesn''t point anywhere meaningful. It''s just a memory address. And that is why just storing a pointer to the string is bad: you don''t have control over its creation or deletion, and you don''t know where it was allocated.

Now, consider my suggestion. When addMessage is called, something like this happens:

void addMessage(char *NewMessage)
{
messageQueue[currentMsgNum] = new char[strlen(NewMessage}+1];
strcpy(messageQueue[currentMsgNum]), NewMessage);
}

Now it doesn''t matter where the message came from; you can delete each element of messageQueue without concern for the string length or whether it''s on the heap or stack.

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

Share this post


Link to post
Share on other sites
I think some clarification on the string problem is needed.

In the following code snippet:

char *a_string = "some text";

no dynamic memory is allocated at run time, so the string isn''t allocated on the heap. The string "some text" is stored in your executable (have a look with a hex editor) in a segment called "rdata" (I''m specifically talking about MSVC V6 here, other compilers may call it something else but the general idea will be there). Your executable has several segments: "text" contains your code, "bss" contains uninitialised global data and so on. "rdata" stands for "read only data", so the above declaration should really be:

const char *a_string = "some text";

which would stop you from deleting it as doing so will generate a compiler error. You will also need to change any functions that take a_string as a parameter to accept a const char *. You should also declare the messageQueue variable as a const char *[] as well. To ''delete'' the message just set the entry in messageQueue to NULL - it will not leak memory since, as stated above, the string is never allocated on the heap.

Remember that a pointer can point to anything, it doesn''t have to be something that was allocated with new/malloc, so it isn''t always necessary to delete what a pointer is pointing at when you''re finished with it.

Note that some compilers / linkers can merge multiple instances of the same string into a single instance, so you can repeat “some text” as many times as you want.

Of course, if you''ve got strings declared in "rdata" and strings allocated via the heap (new / malloc) then ZealousElixir''s solution is required. Or maybe overload the addMessage function to take either a char * or a const char * and have a second, boolean array that is set to true in the first instance and false in the second. When you want to delete the string, check the boolean array first to determine if the string was dynamically or statically allocated.

If you do use dynamically created strings, then you may want to consider using a reference counting system so that the string isn''t deleted until all code that uses it is finished with it.

Skizz

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!