c - 是否在临时变量未定义行为中访问数组?
问题描述
typedef struct test{
char c_arr[1];
} test;
test array[1] = {{1}};
test get(int index){
return array[index];
}
int main(){
char* a = get(0).c_arr;
return *a;
}
在这篇文章中,行为在 C++ 中进行了解释:访问结构内的数组会导致带有 clang 的警告
gcc
上面的代码在使用或编译时不会引起任何警告或错误clang
。
是否get(0).c_arr
返回指向在表达式末尾被销毁的临时变量的指针?如果是这样,是否取消引用并返回其值 UB?如果是这样,那么修复它的好方法是什么,也许是这个?
test* get(int index){
return &array[index];
}
解决方案
char* a = get(0).c_arr;
return *a;
明显是UB;所指的内存a
在运行时已从堆栈中释放,return
相反的结果让我非常恼火。想象一下,如果有人写道:
while (true) {
char a = get(0).c_arr[0];
//...
a = get(0).c_arr[0];
//...
a = get(0).c_arr[0];
//...
a = get(0).c_arr[0];
//...
a = get(0).c_arr[0];
//...
}
堆栈废物臭气熏天,嵌入式程序员和内核程序员会为此而战。
但是,以下内容在 C 中是有效的: char a = get(0).c_arr[0];
这是因为临时保留足够长的时间以在表达式中使用。
推荐阅读
- reactjs - 为什么我的带有 child.type.name 的自定义组件会为每个组件返回一个“t”?
- asp.net - 用于特定页面的非现有目录的 IIS 重写规则到根目录
- python - 安装 flask-mysqldb 时出错
- mysql - 使用大量子查询提高 MYSQL 中的查询性能
- android - 将数据发送到 jsonobject 改造中的字段
- c# - 如何找到射线和三角形的交点?
- haskell - OOP中抽象类对象列表的Haskell对应物
- javascript - 提交带有 React 输入字段的标准 HTML 表单
- android - 在前台的 Android 应用程序中重复调用网络 API
- c++ - 检查操作系统兼容性