#include <stdio.h>
int main() {
FILE *input;
FILE *output;
input = fopen("algsort.in", "r");
output = fopen("algsort.out", "w");
int n = 0;
fscanf(input, "%d", &n); // reads n = 7
int i;
int a[6] = {1, -1, 0, 33, 6, 5};
for(i = 0; i < 8; i++) { // 8 is on purpuse
printf("%d ", a[i]); // the output is [1 -1 0 33 6 5 7 $(Random location in memory)]
}
return 0;
}
fscanf 在数组末尾追加一个元素。这是一个问题,因为它干扰了排序算法,遗漏了一个大于 n 的元素。 我知道 for 循环的限制,问题是,“n”元素仍然是数组的一部分。 问题:7 是从哪里来的?
最佳答案
fscanf
appends an element at the end of the array.
不,它没有。您的数组仍然是六个 int
的数组。您可以越过数组末尾而不会崩溃的事实并不意味着您的数组以某种方式获得了一个额外的元素 - 这意味着这次未定义的行为没有导致崩溃。
Where did the 7 come from?
从内存中 sizeof(int)
的位置开始,经过数组 a
的末尾。通过数组访问此位置是未定义的行为,因此可以返回任何值。 A quick experiment shows至少有一个编译器可以以 n
直接位于数组 a
之后的方式在您的函数中布置内存:
FILE *input = NULL;
FILE *output = NULL;
int n = 0;
scanf("%d", &n); // reads n = 7
int a[6] = {1, -1, 0, 33, 6, 5};
printf("%p\n%p\n", (void*)&n, (void*)&a[6]);
这打印
0xbfabd5e4
0xbfabd5e4
这意味着 n
的地址和 a+6
的值(当你取消引用数组末尾的一个元素时得到的)指向到同一个地址。如果你的编译器做同样的事情,你会看到同样的结果。即使是这种情况,此行为仍未定义。
关于C fscanf 添加一个元素到数组,不应该,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26389139/