C++ 使用C-string会发出警告:“使用C-string”;与返回的局部变量相关联的堆栈内存地址;
我不是C程序员,所以我对C-string不太熟悉,但现在我必须使用C库,因此下面是我的代码的一个简短版本,以演示我的问题:C++ 使用C-string会发出警告:“使用C-string”;与返回的局部变量相关联的堆栈内存地址;,c++,pointers,c-strings,C++,Pointers,C Strings,我不是C程序员,所以我对C-string不太熟悉,但现在我必须使用C库,因此下面是我的代码的一个简短版本,以演示我的问题: char** ReadLineImpl::my_completion () { char* matches[1]; matches[0] = "add"; return matches; } 我收到这样的警告: 警告-返回与局部变量“matches”关联的堆栈内存地址 我的程序似乎不能正常工作(可能是因为上面提到的警告) 这个
char** ReadLineImpl::my_completion () {
char* matches[1];
matches[0] = "add";
return matches;
}
我收到这样的警告:
警告-返回与局部变量“matches”关联的堆栈内存地址
我的程序似乎不能正常工作(可能是因为上面提到的警告)
这个警告意味着什么?它会导致任何问题吗?变量
char*匹配[1]代码>在堆栈上声明,当当前块超出范围时,它将自动释放
这意味着当您返回匹配项
时,为匹配项
保留的内存将被释放,并且您的指针将指向您不想要的内容
您可以通过多种方法解决此问题,其中一些方法是:
将匹配项[1]
声明为静态:静态字符*匹配项[1]代码>-这个
将在静态空间而不是堆栈上为匹配项分配空间(如果您
不适当地使用它,因为my_completion
函数的所有实例
将共享相同的匹配项
变量)
在调用者函数中分配空间并将其传递给my\u completion
功能:myu完成(匹配)
:
在堆上的被调用函数中分配空间(使用malloc
、calloc
和friends)并将所有权传递给调用方函数,调用方函数在不再需要时必须释放此空间(使用free
)
当您返回匹配的
数组时,您返回的是第一个元素的地址。这存储在my\u completion
内的堆栈中。一旦您从my_completion
返回,内存将被回收,并且(很可能)最终将被重新用于其他用途,覆盖存储在匹配项中的值-是的,这可能就是应用程序无法工作的原因-如果不是现在,可能是在您修复了其他一些问题之后,或者稍微改变一下,或者别的什么,因为这不是一个可以安全忽略的小警告
你可以用几种不同的方法来解决这个问题。最明显的是简单地使用std::vector
[或者更好地使用std::vector
]:
std::vector<std::string> ReadLineImpl::my_completion ()
{
std::vector<std::string> strings;
strings.push_back("add");
return strings;
}
问题解决了 变化
char* matches[1];
到
使用堆而不是堆栈
对于这种情况,最好使用以下方法在堆中分配内存:
int* someDataForParams(void *_params) {
...
int* charCounts = calloc(96, sizeof(char*));
...
return charCounts;
}
96只是一个字符串长度(只是一个幻数)您将地址返回到堆栈上分配的第一个字符指针,该指针在退出函数后不再存在。谢谢,我得到了它。最糟糕的是,这是第二次出现这种问题:)无论如何,非常感谢您,因为这是GNU readline
,这将导致崩溃,因为readline
将释放完成函数返回的内存。@MatsPeterson这看起来像是readline-在这种情况下,您是对的。我将投票表决你的答案!声明<代码>匹配< <代码> >代码>静态将在静态空间上分配空间,而不是堆上。第三选项是通过调用CALROCI分配内存,将使用向量作为C++程序员,但库需要char **,所以我必须转换成char **。所以,假设您使用的是 Realth> 接口,然后必须使用malloc分配内存,因为readline
稍后会释放内存。我会编辑。很好,只有一件事,我必须使用(char**)malloc(1*sizeof(char*)),但是谢谢,你的答案更好,尽管我不会改变为什么?也许,你应该描述一下这样做的原因。
char* matches[1];
char *matches = new matches[1];
int* someDataForParams(void *_params) {
...
int* charCounts = calloc(96, sizeof(char*));
...
return charCounts;
}