【问题标题】:Questions about returning char* and memory关于返回 char* 和 memory 的问题
【发布时间】:2020-11-22 14:06:00
【问题描述】:

我刚刚看了一个关于返回 char* 的函数的教程。在本教程中,此功能会打印害虫,但是,当我在计算机上运行此功能时,它不会打印任何内容。 我想知道这是不是因为 s[] 的堆栈内存消失了,存储在 s[] 的字符串是否也消失了。因此,在 main 函数中,string 只是一个空指针。

#include <stdio.h>
#include <stdlib.h>

char* getstring(){
    char s[] = "test";
    return s;
}

int main(int argc, char* argv[]){
    char* string = getstring();
    string[0] = 'p';
    printf("%s", string);
    return 0;
}

【问题讨论】:

  • 你能给我们看看有问题的教程吗?
  • 请不要再看那个系列的教程了。它们显示的是 未定义的行为,因为当使用指向它的指针时,s[] 不再存在。所以你说“s[] 的堆栈内存已经消失”是正确的。
  • @WeatherVane 好的,非常感谢。使用返回 char* 的函数是不好的做法吗?
  • @WeatherVane:你在视频中特别反对什么?我没有看整件事,但是主持人说在char str[] = "test"; 之后返回str 是不合适的,因为str 消失了。这不是演示者的错 OP 使用了被认为不正确的代码。

标签: c


【解决方案1】:

getstring()返回时s失效,但返回的指针string不为空。指针的值不变,但返回后一定不能取消引用指针。这种无效指针和有效指针不容易区分,一定要小心。

【讨论】:

  • so既然string = getstring(),也就是无效的指针s,这就使得string指向了s的同一个地方,但它也是无效的?
  • 关于“指针的值不变”:根据 C 标准,当指针指向的对象的生命周期结束时,指针的值变得不确定(C 2018 6.2.4 2)。原因之一是指针可能不仅仅是一个内存地址,它可能使用辅助数据结构,而当对象的生命周期结束并释放其内存时,辅助数据可能会发生变化,然后仅使用指针的值会导致陷阱或其他奇怪的效果。
【解决方案2】:

在这种情况下,编译器会创建一个足以保存您的字符串的字符数组。问题是,它分配在函数堆栈上,从函数返回后消失。在这种上下文中使用的数组的名称就是它的地址。返回了,但是返回后指向的内存无效。

char* getstring(){
    char s[] = "test";
    return s;
}

在下面的例子中,字符串被分配在一个全局访问的空间中(指针声明是关键)。

const char* getstring(){
    const char s* = "test";
    return s;
}

在上面的例子中,即使从函数返回后,字符串的位置也可以访问。

但是,在这种情况下,您不应尝试修改它。它应该是一个常数。

要使其成为非常数,您应该自己为其分配内存空间并将字符串复制到那里:

char* getstring(){
    char s* = malloc(strlen ("test")+1);
    strcpy(s, "test");
    return s;
}

用完后别忘了free(string)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-10
    • 2012-11-19
    • 2012-05-23
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 2016-08-02
    • 2017-06-22
    相关资源
    最近更新 更多