在这里,我有一个糟糕的节目。它的输出令我困惑,任何人都可以告诉我为什么?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 0;
char *a_result[10];
char *b_result[10];
for (i = 0; i < 10; i++)
{
char a_array[10];
char *b_array = malloc(10*sizeof(char));
int j = 0;
for (j = 0; j < 9; j++)
{
a_array[j] = 'a' + i;
b_array[j] = 'a' + i;
}
a_array[j] = '\0';
b_array[j] = '\0';
a_result[i] = a_array;
b_result[i] = b_array;
}
for (i = 0; i < 10; i++)
printf("a_result: %s b_result: %s\n",a_result[i],b_result[i]);
return 0;
}
我认为a_result和b_result应该是相同的,但事实并非如此。
这是我电脑上的输出。
a_result: jjjjjjjjj b_result: aaaaaaaaa
a_result: jjjjjjjjj b_result: bbbbbbbbb
a_result: jjjjjjjjj b_result: ccccccccc
a_result: jjjjjjjjj b_result: ddddddddd
a_result: jjjjjjjjj b_result: eeeeeeeee
a_result: jjjjjjjjj b_result: fffffffff
a_result: jjjjjjjjj b_result: ggggggggg
a_result: jjjjjjjjj b_result: hhhhhhhhh
a_result: jjjjjjjjj b_result: iiiiiiiii
a_result: jjjjjjjjj b_result: jjjjjjjjj
对此的任何解释都很感激!
答案 0 :(得分:3)
for (i = 0; i < 10; i++)
{
char a_array[10];
...
a_result[i] = a_array;
}
您在for
循环范围内声明堆栈上的数组。这意味着一旦离开for循环,数组将变为无效。也就是说,a_result
内的内容无效。
对于on-stack vairables,编译器将在每个循环中重用a_array
的相同内存区域(不适用于b_array
,因为{{1}将从堆接收到新内存})。因此,对于您的情况,malloc
只复制了10个相同的无效指针。
如果您想要该数组内容的副本,请将a_result
的类型设为
a_result
并使用
char a_result[10][10];
复制到结果中。
答案 1 :(得分:0)
你不断在同一个位置写一个数组(a_array
),然后将地址存入a_result[i]
(a_result
是一个指针数组)。因此,最后,a_result
的每个元素都包含相同的地址(a_array
),a_array
本身具有上次迭代写入的值。
更糟糕的是,在for循环之外访问a_array
的内容(包括通过a_result
中的指针)是未定义的行为。该存储只能在循环体中使用。
相反,您每次迭代都会为b_array
(实际上不是数组)分配新的堆内存,并将此(新)指针存储到b_result
中。因此,您不会覆盖旧值。
答案 2 :(得分:0)
数组
char a_array[10];
在每次循环迭代结束时超出范围,然后在同一内存位置有效地重新创建。你最终会得到一堆指向最后一次重新创建的指针,其中包含“jjjjjj”字符串。