可能的内存泄漏:new char[strlen()]

Possible Memory Leak: new char[strlen()]

本文关键字:strlen char new 内存 泄漏      更新时间:2023-10-16
这是一个

相当基本的问题,我很确定我知道答案,但看到错误的后果是一个段错误,我想我应该问。我已经以以下方式使用 strlen()new char[] 运算符很长一段时间了,只是注意到一些抛出危险信号的东西:

void genericCopy(char *somestring, char *someOtherString) {
    someOtherString = new char[strlen(somestring)];
    strcpy(someOtherString,somestring);
}

我的问题是,看到字符串应该以 null 结尾,我应该这样做吗:

void genericCopy(char *somestring, char *someOtherString) {
    someOtherString = new char[strlen(somestring)+1];
    strcpy(someOtherString,somestring);
    someOtherString[strlen(someOtherString)] = '';
}
到目前为止,我

从未遇到过第一种方法的问题,但这并不意味着我做对了。由于 strlen() 返回的长度是字符串中没有空终止符的字符数,因此 new 不会为"/0"保留空间......至少我不认为是。

首先,你应该知道你的这个函数写起来毫无意义,只需使用strdup(如果您的系统上可用)。

但是,是的,您需要一个额外的字节来存储,因此请始终执行类似 new char[strlen(somestring)+1]; .但是,无需手动添加; strcpy已经这样做了。

你应该使用类似 Valgrind 的东西来发现代码中的这个和类似的错误。

然而,你的代码中还有一个额外的问题;你的代码总是会泄漏someOtherString;它不会返回到你调用它的地方。您需要将方法更改为以下内容:

char *genericCopy(char *something) {
    char *copy = new char[strlen(somestring)+1];
    strcpy(copy,somestring);
    return copy;
}

然后按如下方式获取副本:

copy = genericCopy(something);

或者,您需要将方法更改为以下内容:

void genericCopy(char *something, char **copy) {
    *copy = new char[strlen(somestring)+1];
    strcpy(*copy,somestring);
}

并将其称为:

genericCopy(something, &copy);

如果要使用C++也可以将方法原型更改为:

void genericCopy(char* somestring, char*& someOtherString)

并将其称为:

genericCopy(something, copy);

然后someOtherString将作为引用传递,并且分配给它的新值将在方法之外传播。

是的,你的怀疑是正确的。您应该分配一个额外的字符,并确保复制的字符串以 null 结尾。(strcpy() 本身会这样做,但是当有人建议你切换到 strncpy() 时,他们无疑会这样做(更安全!),你需要格外小心,因为它不能保证复制"/0"。

但是,如果您已经在使用 C++,建议您改用 std::string。它通常是一种更简单、更不容易出错的操作字符数组的方法。

但是,这是您需要解决的进一步问题。您正在将新字符数组分配给 someOtherString 的副本。您需要进行一些更改:

void genericCopy(char *somestring, char **someOtherString) {
    *someOtherString = new char[strlen(somestring)+1];
    strcpy(*someOtherString,somestring);
    (*someOtherString)[strlen(somestring)] = '';
}

这样,您将在函数调用之外取回新的字符缓冲区。