为什么在编译时会收到“警告:函数返回局部变量[-Wreturn-local-addr]的地址”?

时间:2018-09-30 08:37:31

标签: c arrays pointers

编辑:编辑了我的问题。感谢@SomeProgrammerDude帮助我了解我做错了什么(我在混淆数组和指针,这是一个对我有帮助的相关主题:Difference between array type and array allocated with malloc)。

假设我在函数内部声明并初始化了一个数组'a',如果我在函数外部声明了指针'b'并尝试返回转换为指针的'a':

uint8_t *b;

uint8_t * foo(void){
    unint8_t a[size] = {'a', 'b', ...};

    return (uint8_t *) a;
}

b = foo(b);

我为什么得到:

warning: function returns address of local variable [-Wreturn-local-addr]

1 个答案:

答案 0 :(得分:1)

我有点猜测,因为不清楚您想知道的是什么,但是我想您是在问ab是否都在分配后都指向相同的内存c = a

在这种情况下,答案是肯定的。

+---+     +-------------------------------+
| a | --> | Memory allocated by malloc... |
+---+     +-------------------------------+

如果我们以图形方式查看它,a = malloc(...)之后,您会看到类似的东西

+---+     +-------------------------------+
| a | --> | Memory allocated by malloc... |
+---+     +-------------------------------+

然后在分配c = a之后,您会得到类似

+---+
| a | --\
+---+    \     +-------------------------------+
          >--> | Memory allocated by malloc... |
+---+    /     +-------------------------------+
| c | --/
+---+

return c之后,使用b = foo(b),则只有

+---+     +-------------------------------+
| b | --> | Memory allocated by malloc... |
+---+     +-------------------------------+

重要说明:除非您以其他方式知道分配的内存大小,否则使用分配的内存可能会很麻烦,因为您不知道内存的结束位置。越界导致undefined behavior

但是,只要您停留在分配的内存范围之内,就可以随意使用它。您可以通过取消引用指针b来对其进行写入或读取。


另一个重要说明:将参数传递到foo是无关紧要的,foo函数可以很容易地完成return a而不用担心参数,并且最终结果(b指向内存)将是相同的:

uint8_t foo(void)
{
    uint8_t *a = malloc(...);
    return a;
}

甚至不需要变量a

uint8_t foo(void)
{
    return malloc(...);
}

使用以上两个功能,b = foo()之后的最终结果仍然是

+---+     +-------------------------------+
| b | --> | Memory allocated by malloc... |
+---+     +-------------------------------+