首页 > 解决方案 > 为什么我在编译时收到“警告:函数返回局部变量 [-Wreturn-local-addr] 的地址”?

问题描述

编辑:编辑我的问题。感谢@SomeProgrammerDude 帮助我理解我做错了什么,(我混淆了数组和指针,这是一个帮助我的相关主题:数组类型和使用 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]

标签: carrayspointers

解决方案


我在这里有点猜测,因为不清楚你到底想知道什么,但我想你是在问,如果ab两者都在分配后指向相同的记忆c = a

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

+---+ +------------------+
| 一个 | --> | malloc 分配的内存... |
+---+ +------------------+

如果我们以图形方式看待它,在a = malloc(...)你有类似的东西之后

+---+ +------------------+
| 一个 | --> | malloc 分配的内存... |
+---+ +------------------+

然后在分配之后c = a你有类似的东西

+---+
| 一个 | --\
+---+ \ +-------------------+
          >--> | malloc 分配的内存... |
+---+ / +-------------------+
| c | --/
+---+

return c,b = foo(b)之后你只有

+---+ +------------------+
| 乙 | --> | malloc 分配的内存... |
+---+ +------------------+

重要提示:除非您以其他方式知道分配内存的大小,否则使用分配的内存可能会很麻烦,因为您不知道它在哪里结束。越界会导致未定义的行为

但是,只要您保持在分配内存的范围内,您就可以随意使用它。您可以通过取消引用指针来写入或读取它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()仍然是

+---+ +------------------+
| 乙 | --> | malloc 分配的内存... |
+---+ +------------------+

推荐阅读