c - 为什么我在编译时收到“警告:函数返回局部变量 [-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]
解决方案
我在这里有点猜测,因为不清楚你到底想知道什么,但我想你是在问,如果a
和b
两者都在分配后指向相同的记忆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 分配的内存... | +---+ +------------------+
推荐阅读
- listview - 在列表视图中切换标签的可见性
- r - 格式化时间戳
- node.js - nodeJS/Express TypeError:无法读取未定义的属性“方法”
- ubuntu - 在 Ubuntu 中将 WilfFly 作为服务运行时没有日志
- adaptive-cards - 尝试制作表格时自适应卡片未显示所有键和值
- reactjs - 如何在功能性 React 组件中使用动态 JS 库(wavesurfer.js)?
- java - 在为图像设置动画时,我在 android studio 中遇到空对象引用错误
- python - python中字符串替换期间的内存错误
- javascript - Redux 异步问题 - 无法读取未定义的属性“名称”
- c - 使用正确的循环使用校对我的代码