可以/为什么在返回类型中使用char *而不是const char *会导致崩溃?

我在某处读到如果你想要一个C / C ++函数来返回一个字符数组(而不是std :: string),你必须返回const char *而不是char *。 执行后者可能会导致程序崩溃。

有人能够解释这是否属实? 如果是真的,为什么从一个如此危险的函数返回一个char *? 谢谢。

const char * my_function() { .... } void main(void) { char x[] = my_function(); } 

如果你有一个返回“字符串文字”的函数,那么它必须返回const char *。 这些不需要由malloc在堆上分配,因为它们被编译为可执行文件本身的只读部分。

例:

 const char* errstr(int err) { switch(err) { case 1: return "error 1"; case 2: return "error 2"; case 3: return "error 3"; case 255: return "error 255 to make this sparse so people don't ask me why I didn't use an array of const char*"; default: return "unknown error"; } } 

你被告知的事实并非如此。

返回一个const char *可以改善函数的语义(即不要弄乱我给你的东西)但是返回一个char *就完全没问了。

但是,在任何一种情况下,都必须确保返回在my_function分配在堆上的char *const char * (即使用mallocnew分配),否则每当my_function返回时, [const] char *的内存[const] char *将被取消分配,您将访问无效指针。

最后你必须记得freedelete一旦你完成它后返回给你的[const] char * ,否则你会泄漏内存。 C / C ++不是这么好的语言吗?

所以,在C中,你会有

 const char *my_function() { const char *my_str = (const char *)malloc(MY_STR_LEN + 1); // +1 for null terminator. /* ... */ return my_str; } int main() { const char *my_str = my_function(); /* ... */ free(my_str); /* ... */ return 0; } 

通常,这不是问题,但有些事情需要考虑。 这通常是const-correctness的问题,这意味着要记录你可以改变的东西和你不能改变的东西。

如果你要返回一个双引号字符串,它是const char * ,并且像其他任何东西一样处理它是一个麻烦的邀请。 更改此类字符串是未定义的行为,但通常会导致程序崩溃或更改该字符串的任何位置。

如果在堆栈上返回一个字符数组(即一个被调用函数的局部变量),它就会消失,并且指针将指向任何特定的东西,可能在某个时候结果不好。

如果被调用函数返回的内容已经是const char * ,那么将其更改为char *需要强制转换。 此外,如果你真的要改变它,你需要确保它是可以改变的。 将它保存为const char *通常要好得多。

返回使用malloc()new分配的内存没有直接问题,但是你确实存在所有权问题:应该free()什么函数free() / delete它,何时以及如何处理可能的副本? 这就是C ++的智能指针闪耀的地方。

如果在堆栈上分配了char *,则返回一个悬空指针。 否则,只要它匹配函数的原型并且声明与返回值匹配,你应该没问题。

只需更改返回代码就不会导致崩溃。 但是,如果返回的字符串是静态的(例如return "AString" ),则应返回const char *以确保编译器检测到对该内存的任何尝试修改,这可能会导致崩溃。 你当然可以使用强制转换等来绕过编译器检查,但在这种情况下,你必须努力使崩溃发生。