【问题标题】:How char[] and char* are different in this case?在这种情况下 char[] 和 char* 有何不同?
【发布时间】:2011-09-17 06:08:34
【问题描述】:

当我们运行这段代码时,它运行正常,并在屏幕上打印string constant

char *someFun(){
    char *temp = "string constant";
    return temp;
}
int main(){
    puts(someFun());
}

但是当我们运行下面类似的代码时,它不会工作并且会在屏幕上打印一些垃圾:

char *someFun1(){
    char temp[ ] = "string";
    return temp;
}
int main(){
    puts(someFun1());
}

这背后的原因是什么?本质上,这两个函数都做类似的事情(即返回一个“字符串”),但它们的行为仍然不同。这是为什么呢?

【问题讨论】:

    标签: c string pointers dangling-pointer


    【解决方案1】:
    char *temp = "string constant";
    

    string constant 文字位于只读段上。它在程序终止时被释放。所以,你可以有一个引用指向它。

    char temp[ ] = "string";
    

    string 被复制到位于堆栈上的temp。当函数返回时,堆栈的展开开始释放函数范围内的变量。但是您正在返回对它的引用,该引用不再存在于堆栈中,因此您得到了垃圾。但有时你可能仍然会得到正确的结果,但你不应该依赖它。

    【讨论】:

    • 参数、控制信息(如返回地址和帧指针)以及puts() 中的局部变量可能正在使用someFun1() 中的局部变量(数组)先前使用的空间。
    • 顺便说一句,为避免在处理字符串文字时出现问题,您应该将指向它们的指针存储在 const char * 变量中,因此如果您尝试修改它们,编译器会阻止您。
    【解决方案2】:

    在第一种情况下,指针temp 将指向一个存储"string constant" 的全局常量。因此,当你返回指针时,它是有效的。

    在第二种情况下,'"string"' 只是堆栈上的一个 char 数组 - 从函数返回后它会死掉。

    【讨论】:

    • 为什么在第一种情况下存储在全局堆中,而在第二种情况下存储在本地堆栈中?
    • 默认情况下,字符串字面量是全局存储的。 (不是在堆上,而是在程序内存中)但是,当您声明 char[] 时,您可以将字符串作为 {'s','t','r','i','n','g'} 的缩写形式放在那里。
    • ...包括空终止符。
    猜你喜欢
    • 2022-01-03
    • 2017-09-22
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 2019-10-14
    • 2015-01-01
    • 1970-01-01
    • 2016-05-15
    相关资源
    最近更新 更多