possible memory leak

Started by
3 comments, last by snk_kid 18 years, 11 months ago
I am making a Gui system in openGl/SDL for input and am having trouble implementing text boxes. It works for a bit and then every 10 or so chars it will pop in a random word like BLUE which happens to be a caption of a label. I have been toying around with it for about half an hour and can't get it solved. I'm trying to make it add the char to the end of the string and allocate memory with it. Using std::string probably would be easier but my print function does not handle them. This is the code I am using that seems to be the problem.

Uint8* keys;    // Stores the keys	
    keys = SDL_GetKeyState(NULL);	// Get key states
    for(int i = 32;i < 126;i++)
    {
        if(keys == true)
        {
            char* tempCaption;
            tempCaption = new char[strlen(caption) + 1];
            strcpy(tempCaption,caption);
            char temp = char(i);    // Get the char
            delete [] caption;  // Delete current caption
            int length = strlen(tempCaption) + 1;
            caption = new char[length]; // Allocate new memory
            // Copy it
            strcpy(caption,tempCaption);
            caption[strlen(tempCaption)] = temp;
            keys = false;
            delete [] tempCaption;
            break;
        }
    }

I can't seem to find the problem with that and I can't see how words could be getting into the input stream. And also once it gets so many letters it will just crash. I also have the function that changes the labels caption.

void Label::Caption(char* t,...)
{
    char text[256];	// Holds string
    va_list ap;	//Pointer to list of arguments
    if(t == NULL)	//No text
        return;	//Return
     
    va_start(ap,t);	//Pares the string for variables
    vsprintf(text,t,ap);	//Convert symbols to numbers
    va_end(ap);	//Results stored in text
    
    int length = strlen(text) + 1;  // Find length
    delete [] caption;  // Free old memory
    caption = new char[length]; // Allocate new memory
    strcpy(caption,text);   // Copy the text
}

I can't seem to pin-point the problem. If anyone could help spot the problem I would really appreciate it. Thanks, vbuser
Advertisement
First off, use std::string!

If you want to keep using char pointers you've made a little mistake. You have allocated caption with 1 longer than tempCaption to store the extra charcter that you are adding, but you have failed to take into account the null byte that has to come at the end of a C string


int length = strlen(tempCaption) + 2;
caption = new char[length];
strcpy(caption,tempCaption);
caption[strlen(tempCaption)] = temp;
caption[strlen(tempCaption) + 1] = \0;

To clarify a little bit the string manipulation functions expect that your char* will be terminated with a null byte. This is how they determine where the end of the string is. When you don't provide this they will continue to assume that the memory after your string is actually part of your string, leading to odd characters on the end.

Also if you continue with this approach you should be able to accomplish it with only one allocation and you should try to cache the length instead of using strlen() so many times.
You do realise that std::string has a c_str method that allows you to extract a C-style, null terminated string from it?

Here's an example usage:
if(keys == true){	std::string newCaption(caption);	newCaption += (char)i; //See how easy it is to add stuff to a std::string	delete [] caption; // Delete current caption	caption = new char[newCaption.length() + 1]; //+ 1 for null terminal	strcpy(caption, newCaption.c_str());	keys = false;	break;}

The best solution, however, is to replace caption with a std::string and whenever you need a char *, just use the c_str() method. Better yet, make caption an istringstream class and then you can add any thing to it, such as ints or floats etc, without having to use the nasty sprintf! Just call str() to get a std::string, and then call c_str() on that to get your C-style string (i.e. call str().c_str())

HTH
Thanks I forgot about adding the null-char when I changed the last char. But I am doing with std::string now so that I just use.c_str and it works much better now.

Thanks for the help,
vbuser
What your really looking for is using std::string and string streams such as std::stringstream, std::istringstream, and std::ostringstream.

And yes localization/internalization can be done with these.

This topic is closed to new replies.

Advertisement