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

时间:2012-07-07 04:57:24

标签: c++ memory-leaks

这是一个相当基本的问题,我很确定我知道答案,但是看到错误的结果是我认为我应该问的一个段错误。我一直在以下方式使用strlen()new char[]运算符已经有一段时间了,只是发现了一些引发红旗的事情:

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

我的问题是,看到字符串应该为空终止,我应该这样做:

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

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

2 个答案:

答案 0 :(得分:3)

首先,你应该知道你的这个功能是没有意义的,只需使用strdup(如果在您的系统上可用)。

但是,是的,你需要一个额外的字节来存储\0,所以总是做new char[strlen(somestring)+1];之类的事情。但是,无需手动添加\0; 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将作为参考传递,您分配给它的新值将传播到您的方法之外。

答案 1 :(得分:1)

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

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

但是,这是您需要解决的另一个问题。您将新的字符数组分配给someOtherString的COPY。你需要做一些改变:

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

这样你就可以在函数调用之外找回新的字符缓冲区。