【问题标题】:Why does the value of a pointer of a pointer have undefined behaviour?为什么指针的指针的值具有未定义的行为?
【发布时间】:2021-09-02 22:58:37
【问题描述】:

这是我的代码

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

char ** func()
{
    char list[2][20] = {"a140","3.14"};
    char * l[2] = {list[0], list[1]};
    char ** point = l;
    return point;
}

int main()
{
    char ** pointers;
    pointers = func();
    printf("%d", *pointers[0]);
}

在这里,我试图调用一个函数,该函数返回一个指针数组,该指针数组指向包含字符的数组的值。

但是出了点问题,当我运行这段代码时,它会输出:

97

【问题讨论】:

  • 这是因为您正在返回一个指向局部变量的指针。局部变量在函数退出时失效,之后使用就是UB。
  • 一种方法是动态分配需要超过函数寿命的内存。但是你需要记住在完成后释放它。
  • 你期待什么而不是97
  • 您实际上得到了“正确”的结果,因为 97 是 a 的 ASCII 码,即 l[0][0]。但是你不能依赖这种情况,因为你有未定义的行为。
  • 因为*pointerschar ***pointers 是一个字符。

标签: c pointers undefined-behavior


【解决方案1】:

返回的值是一个指向局部变量的指针,特别是&amp;l[0]。函数返回后,该变量的生命周期结束。因此,当您尝试取消引用返回的指针时,您是在尝试在其生命周期结束后访问一个对象。这会触发undefined behavior

您的函数需要为要返回的字符串数组动态分配内存。

const char **func()
{
    const char **l = malloc(2 * sizeof *l);
    l[0] = "a140";
    l[1] = "3.14";
    return l;
}

还请注意,输出将保持不变,因为您要打印的是第一个字符串的第一个字符的 ASCII 值。如果要打印整个字符串,请不要取消引用 pointers[0] 并使用 %s 格式说明符:

printf("%s", pointers[0]);

【讨论】:

  • 能否请您解释一下这段代码是如何工作的,主要是 malloc 以及为什么要返回 1。
  • @EvandroFilipe malloc 函数动态分配内存,并且该内存在程序的生命周期内保持有效(或直到它传递给free)。返回的是变量 l 的值,而不是数字 1。
  • 我如何传递这个内存来释放或者我不需要?
  • @EvandroFilipe 使用完内存后,请致电free(pointers)
  • 感谢您对我非常耐心并给了我答案。对不起,如果我很烦人。
【解决方案2】:

你也可以


char ** func(void)
{
    static char *list[] = {"a140","3.14"};
    return list;
}

/* LOL everything is list */
typedef struct
{
    char *list[2];
}list;

list func(void)
{
    list list = {{"a140","3.14"}};
    return list;
}

int main(void)
{
    char **list = (func()).list;

    printf("%s %s\n", list[0], list[1]);
}

https://godbolt.org/z/hhjK8G7TP

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多