简体   繁体   中英

Char* related memory leak

I am running Valgrind to check my code for memory leaks. Valgrind doesn't show any leaks happening but I have a piece of code that I believe should be causing a leak and I don't understand how the variables are being cleaned up or Valgrind isn't catching it. Why do the two char* arrays not create a leak?

void BasicEngine::ConnectionInput(int ConnectionId, const char* ClientInput)
{

    // find client assignment to this ConnectionId
    Client* thisClient = this->ClientFind(ConnectionId);

    int SpaceLocation = strcspn(ClientInput," ");

    char* verb;
    char* args;

    if(SpaceLocation == strlen(ClientInput))
    {
        verb = (char*)ClientInput;
        args = (char*)"";
    }
    else
    {
        verb = new char[SpaceLocation+1];
        args = new char[strlen(ClientInput)-SpaceLocation+1];

        sscanf(ClientInput,"%s %[^\n]",verb,args);
    }


    if(thisClient != NULL)
    {    
       // ... client is always null, this is not being reached at the moment.
    }
    else   
    {
        if(this->refCmdHandler != NULL)
         if(this->refCmdHandler->cmdHandler(ConnectionId,ClientInput))
            return;
    }

    this->refServer->TransmitNL(ConnectionId,"Invalid Command.");

}


bool BasicCmdProc::cmdHandler(int ConnectionId, string ClientInput)
{
    Transmit(ConnectionId,string("You Said: ") + ClientInput);

    return true;
}

If I type in 'hello'

output is: You said: hello

and no leaks are detected.

hello contains no spaces, so strcspn returns strlen(ClientInput) and so you take the first branch. In that branch, verb and args are not dynamically allocated, so there's no leak.

Note, however, that it is usually very dangerous to have a variable point at "maybe-allocated" memory, because it will be harder to determine if the variable should be freed. You should therefore use new in both branches, and unconditionally free both variables at the end. Or, better yet, use std::string s and avoid this issue altogether.

Neither of the two char * elements verbs or args is allocated when the input is hello because:

int SpaceLocation = strcspn(ClientInput," ");

char* verb;
char* args;

if (SpaceLocation == strlen(ClientInput))
{
    verb = (char*)ClientInput;
    args = (char*)"";
}
else
{
    verb = new char[SpaceLocation+1];
    args = new char[strlen(ClientInput)-SpaceLocation+1];

    sscanf(ClientInput,"%s %[^\n]",verb,args);
}

the output from strcspn(ClientInput, " ") , aka SpaceLocation , is the same as strlen(ClientInput) , so the new[] operation is not executed and no memory is allocated.

How will you tell whether or not you need to release verb and args ? Not knowing whether to release memory is dangerous.

Why do the two char* arrays not create a leak?

They only do when you assign the result of the new operator to them (and in this case, Valgrind should be notifying you). If you assign constant strings to them, then there's no memory to be leaked - constant strings are alive under the whole lifetime of the program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM