为什么在返回类型中使用 char * 而不是 const char * 会导致崩溃?
我在某处读到,如果您希望 C/C++ 函数返回字符数组(而不是 std::string),则必须返回 const char* 而不是 char*。执行后者可能会导致程序崩溃。
有人能解释一下这是否属实吗?如果这是真的,为什么从函数返回 char* 如此危险?谢谢。
const char * my_function()
{
....
}
void main(void)
{
char x[] = my_function();
}
I read somewhere that if you want a C/C++ function to return a character array (as opposed to std::string), you must return const char* rather than char*. Doing the latter may cause the program to crash.
Would anybody be able to explain whether this is true or not? If it is true, why is returning a char* from a function so dangerous? Thank you.
const char * my_function()
{
....
}
void main(void)
{
char x[] = my_function();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您有一个返回“字符串文字”的函数,那么它必须返回 const char*。这些不需要由 malloc 在堆上分配,因为它们被编译成可执行文件本身的只读部分。
例子:
If you have a function that returns "string literals" then it must return const char*. These do not need to be allocated on the heap by malloc because they are compiled into a read-only section of the executable itself.
Example:
您被告知的情况不是真的。
返回
const char *
可以改进函数的语义(即不要混淆我给你的内容),但返回char *
就完全没问题了。但是,无论哪种情况,您必须确保返回一个
char *
或const char *
在my_function
的堆上分配(即使用malloc
或new
分配),否则每当my_function
返回时,内存因为[const] char *
将被释放,并且您将访问无效的指针。最后,您必须记住
释放
或删除
[const] char *
一旦你完成它,它就会返回给你,否则你会泄漏内存。 C/C++ 不是很棒的语言吗?所以,在 C 语言中,你会得到
What you were told is not true.
Returning a
const char *
can improve the semantics of a function (i.e. don't mess with what I'm giving you) but returning achar *
is perfectly fine.However, in either case, you must make sure that you return a
char *
orconst char *
that was allocated on the heap inmy_function
(i.e. allocated usingmalloc
ornew
), otherwise whenevermy_function
returns, the memory for the[const] char *
will be deallocated, and you will be accessing an invalid pointer.And finally you must remember to
free
ordelete
the[const] char *
that's been returned to you once you're done with it, or you will leak memory. Aren't C/C++ such great languages?So, in C, you would have
通常,这不是问题,但有一些事情需要考虑。这通常是一个常量正确性的问题,这意味着跟踪可以更改的内容和不能更改的内容。
如果您返回一个双引号字符串,则它是 const char *,并且像其他任何东西一样对待它会带来麻烦。更改此类字符串是未定义的行为,但通常会导致程序崩溃或更改该字符串(无论在何处引用)。
如果您在堆栈上返回一个字符数组(即,被调用函数的局部变量),它将消失,并且指针将指向任何特定内容,有时可能会产生不良结果。
如果被调用函数返回的内容已经是
const char *
,则将其更改为char *
需要进行强制转换。此外,如果您确实要更改它,您需要确保它是可以更改的。通常最好将其保留为const char *
。返回使用
malloc()
或new
分配的内存不会立即出现问题,但确实存在所有权问题:什么函数应该free()
>/删除
它,何时删除,以及如何处理可能的副本?这就是 C++ 智能指针的闪光点。Usually, that isn't an issue, but there are things to consider. It's usually a matter of const-correctness, which means keeping track of what you can change and what you can't.
If you're returning a double-quoted string, it's
const char *
, and treating it like anything else is an invitation for trouble. Changing such a string is undefined behavior, but will usually cause the program to crash or change that string wherever it's referred to.If you return a character array on the stack (i.e., a called function's local variable), it will go away, and the pointer will point to nothing in particular, probably with bad results at some time.
If the called function is returning something that's already
const char *
, then changing it tochar *
requires a cast. Further, if you're actually going to change it, you need to be sure it's changeable. It's usually much better to keep it asconst char *
.There's no immediate problem with returning memory allocated with
malloc()
ornew
, but you do have the problem of ownership: what function shouldfree()
/delete
it, when, and what do you do about possible copies? This is where C++'s smart pointers shine.如果 char* 是在堆栈上分配的,则返回一个悬空指针。否则,只要它与函数的原型匹配并且声明与返回值匹配,就应该没问题。
If the char* is allocated on the stack, you return a dangling pointer. Otherwise, so long as it matches the function's prototype and the declaration matches the return value, you should be fine.
简单地更改返回代码不会导致崩溃。但是,如果您返回的字符串是静态的(例如
return "AString"
),则应返回const char *
以确保编译器检测到对该内存的任何尝试修改,这可能会导致崩溃。您当然可以使用强制转换等来绕过编译器检查,但在这种情况下,您必须努力才能使崩溃发生。Simply changing the return code won't cause a crash. However if the string you return is static (for example
return "AString"
), you should returnconst char *
to make sure that the compiler detects any attempted modification of that memory, which will likely cause a crash. You can certainly use casts and such to get around the compiler checks, but in that case you'd have to work to make the crash happen.