我有以下情况:
#include <stdio.h>
struct A {
double* a;
};
struct A data = {
(double[]) {1.1, 1.2, 1.3}
};
void f() {
data.a[2] = 2.2;
printf("%f\n", data.a[2]); // situation 1
}
int main() {
f();
printf("%f\n", data.a[2]); // situation 2
}
我想知道这两个标记的情况是否是未定义的行为。我相信情况 1 不是未定义的行为(一旦我仅在 f
中使用 data
),但情况 2 实际上是。
在不是未定义行为的情况下,如果我将 f
中的 data.a[2] = 2.2;
更改为 data.a = (double []) {2.1, 2.2, 2.3};
,我会得到未定义的行为吗?
最佳答案
I'd like to know if the two labeled situations are undefined behaviors or not. I believe that situation 1 is not a undefined behavior (once I use data only inside f),
C 规定了所有涉及的运算符的行为,并且对它们与示例代码中出现的对象或事件序列的使用没有限制。因此定义了行为。
but situation 2 actually is.
C 规定了所有涉及的运算符的行为,并且对它们与示例代码中出现的对象或事件序列的使用没有限制。因此定义了行为。
对象 data
在文件范围内声明,因此它的生命周期跨越程序的整个运行。它的一个成员是用指向数组第一个元素的指针初始化的,该数组表示为复合文字,并且由于该复合文字出现在任何函数的主体之外,因此它的生命周期也跨越了程序的整个运行。此外,它的类型(在本例中)是 double[3]
,它不是 const
限定的,因此它的元素可能被分配给。
In the case of not being undefined behavior, if I change data.a[2] = 2.2; inside f to data.a = (double[]) {2.1, 2.2, 2.3};, I would get undefined behavior?
是的,在 main()
中。出现在函数体内部的复合文字具有自动持续时间,因此它的生命周期不会晚于函数返回时结束。在这一点上,任何指向或进入它的指针都变得不确定,并且任何取消引用它们的尝试(如 main
此后所做的那样)都具有未定义的行为。
关于c - 未定义的行为是否改变了文字数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57117167/