C++ 与字符相关的内存泄漏

C++ 与字符相关的内存泄漏,c++,memory,memory-leaks,C++,Memory,Memory Leaks,我正在运行Valgrind来检查我的代码是否存在内存泄漏。Valgrind没有显示发生了任何泄漏,但我有一段代码,我认为应该导致泄漏,我不明白变量是如何清理的,或者Valgrind没有捕捉到它。为什么这两个char*数组不产生泄漏 void BasicEngine::ConnectionInput(int ConnectionId, const char* ClientInput) { // find client assignment to this ConnectionId

我正在运行Valgrind来检查我的代码是否存在内存泄漏。Valgrind没有显示发生了任何泄漏,但我有一段代码,我认为应该导致泄漏,我不明白变量是如何清理的,或者Valgrind没有捕捉到它。为什么这两个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;
}
如果我输入“你好”

输出是:你说:你好


并且未检测到泄漏。

当输入为
hello
时,两个
char*
元素
verbs
args
均未分配,因为:

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);
}
strcspn(ClientInput,””
,也称为
SpaceLocation
,的输出与
strlen(ClientInput)
相同,因此不会执行
新[]
操作,也不会分配内存


如何判断是否需要释放
动词
参数
?不知道是否释放内存是危险的。

当输入为
hello
时,两个
char*
元素
动词
args
均未分配,因为:

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);
}
strcspn(ClientInput,””
,也称为
SpaceLocation
,的输出与
strlen(ClientInput)
相同,因此不会执行
新[]
操作,也不会分配内存

如何判断是否需要释放
动词
参数
?不知道是否释放内存是危险的

为什么这两个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;
}
只有当您将
new
操作符的结果分配给他们时,他们才会这样做(在这种情况下,Valgrind应该通知您)。如果将常量字符串分配给它们,那么就不会有内存泄漏——常量字符串在程序的整个生命周期内都是活动的

为什么这两个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;
}

只有当您将
new
操作符的结果分配给他们时,他们才会这样做(在这种情况下,Valgrind应该通知您)。如果您将常量字符串分配给它们,那么就不会有内存泄漏-常量字符串在程序的整个生命周期内都是活动的。

hello
不包含空格,因此
strcspn
返回
strlen(ClientInput)
,因此您执行第一个分支。在该分支中,
verb
args
不是动态分配的,因此没有泄漏


但是,请注意,在“可能已分配”内存中有一个变量点通常是非常危险的,因为很难确定是否应该释放该变量。因此,您应该在两个分支中使用
new
,并在末尾无条件释放这两个变量。或者,最好使用
std::string
s并完全避免此问题。

hello
不包含空格,因此
strcspn
返回
strlen(ClientInput)
,因此您选择第一个分支。在该分支中,
verb
args
不是动态分配的,因此没有泄漏


但是,请注意,在“可能已分配”内存中有一个变量点通常是非常危险的,因为很难确定是否应该释放该变量。因此,您应该在两个分支中使用
new
,并在末尾无条件释放这两个变量。或者,更好的方法是使用
std::string
s,并完全避免这个问题。

为什么要使用数组而不是
vector
s?你的意思是
string
,@BartekBanachewicz?我认为
vector
将是处理字符串的一种不寻常的方式。那可能是深夜+我最近做了太多奇怪的IO。你为什么使用数组而不是
vector
s呢?你的意思是
string
,@BartekBanachewicz?我认为
vector
将是处理字符串的一种不寻常的方式。这可能是深夜+我最近做了太多奇怪的IO。我尝试了“hello world”作为输入,但仍然得到了相同的结果,即没有内存泄漏。将char*数组传递给字符串参数会对此产生一些影响吗?这是我唯一能想到的。我尝试了“hello world”作为输入,但仍然得到相同的结果,没有内存泄漏。将char*数组传递给字符串参数会对此产生一些影响吗?这是我唯一能想到的。