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

发布于 2024-08-04 12:07:21 字数 264 浏览 2 评论 0原文

我在某处读到,如果您希望 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ぺ禁宫浮华殁 2024-08-11 12:07:21

如果您有一个返回“字符串文字”的函数,那么它必须返回 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";
    }
}

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* 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";
    }
}
囚我心虐我身 2024-08-11 12:07:21

您被告知的情况是真的。

返回 const char * 可以改进函数的语义(即不要混淆我给你的内容),但返回 char * 就完全没问题了。

但是,无论哪种情况,您必须确保返回一个 char *const char *my_function 的堆上分配(即使用 mallocnew 分配),否则每当 my_function 返回时,内存因为 [const] char * 将被释放,并且您将访问无效的指针。

最后,您必须记住释放删除[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;
}

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 a char * is perfectly fine.

However, in either case, you must make sure that you return a char * or const char * that was allocated on the heap in my_function (i.e. allocated using malloc or new), otherwise whenever my_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 or delete 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 *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;
}
回忆那么伤 2024-08-11 12:07:21

通常,这不是问题,但有一些事情需要考虑。这通常是一个常量正确性的问题,这意味着跟踪可以更改的内容和不能更改的内容。

如果您返回一个双引号字符串,则它是 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 to char * 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 as const char *.

There's no immediate problem with returning memory allocated with malloc() or new, but you do have the problem of ownership: what function should free()/delete it, when, and what do you do about possible copies? This is where C++'s smart pointers shine.

带刺的爱情 2024-08-11 12:07:21

如果 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.

南街女流氓 2024-08-11 12:07:21

简单地更改返回代码不会导致崩溃。但是,如果您返回的字符串是静态的(例如 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 return const 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文