简体   繁体   English

与Char *相关的​​内存泄漏

[英]Char* related memory leak

I am running Valgrind to check my code for memory leaks. 我正在运行Valgrind以检查我的代码是否存在内存泄漏。 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. Valgrind没有显示任何泄漏发生,但是我有一段代码,我相信应该导致泄漏,并且我不明白变量是如何被清除的,或者Valgrind没有捕获到。 Why do the two char* arrays not create a leak? 为什么两个char *数组不创建泄漏?

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' 如果我输入“ 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. hello包含空格,因此strcspn返回strlen(ClientInput) ,因此您进入了第一个分支。 In that branch, verb and args are not dynamically allocated, so there's no leak. 在该分支中, verbargs不会动态分配,因此不会泄漏。

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. 因此,您应该在两个分支中都使用new ,并在末尾无条件释放两个变量。 Or, better yet, use std::string s and avoid this issue altogether. 或者,更好的是,使用std::string并完全避免此问题。

Neither of the two char * elements verbs or args is allocated when the input is hello because: 输入为hello时,两个char *元素verbsargs均未分配,因为:

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. strcspn(ClientInput, " ") (又名SpaceLocation strcspn(ClientInput, " ")的输出与strlen(ClientInput)相同,因此不会执行new[]操作,也不会分配内存。

How will you tell whether or not you need to release verb and args ? 您如何判断是否需要释放verbargs Not knowing whether to release memory is dangerous. 不知道是否释放内存很危险。

Why do the two char* arrays not create a leak? 为什么两个char *数组不创建泄漏?

They only do when you assign the result of the new operator to them (and in this case, Valgrind should be notifying you). 它们仅在您将new运算符的结果分配给它们时才起作用(在这种情况下,Valgrind应该通知您)。 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. 如果为常量字符串分配常量字符串,则不会有内存泄漏-常量字符串在程序的整个生命周期中都有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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