Malloc 的 char 数组有意外的输出
Malloc'd char array has unexpected output
我的问题很简单,我不明白为什么这个程序不能正确输出:
int size = 35;
// malloc size for text
char *txt = malloc(size * sizeof(char *));
if(!txt) {
fprintf(stderr, "Allocation for text data failed.\n");
return EXIT_FAILURE;
}
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
printf("%s\n", txt);
free(txt);
预期输出:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
实际输出:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8 9 10 1 0
12 11 6 37 44 3 45 56 0 64 77 5 68 83 0
39 46 0 19 16 9 8 2 6 3 1 4 17 12 9
17 6 0 25 10 3 31 16 13 21 9 9 11 7 4
2 3 0 7 6 1 9 5 2 11 2 5 19 6 13
21 8 15 8 0 0 7 0 0 29 20 13 62 50 0
49 35 0 41 27 1 38 25 9 25 13 0 21 11 0
24
尝试使用 valgrind --leak-check=yes
调试 ,它显示的唯一错误如下:
==3999== Conditional jump or move depends on uninitialised value(s)
==3999== at 0x4C30F78: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3999== by 0x4EA969B: puts (ioputs.c:35)
==3999== by 0x400B39: main (decode.c:85) // this is the printf line
我以为是不知道什么时候停止打印,结果试了:
while(txt != NULL) {
printf("%c", *(txt++));
}
我也试过了:
txt[size - 1] = '[=12=]';
while((*txt) != '[=12=]') {
printf("%c", *(txt++));
}
那些会产生更糟糕的结果,因为它会用特殊字符填充我的控制台。
将 [=11=]
放入 char 数组中。否则 printf
将有 undefined behavior
.
同样在 malloc
中,您分配给 char
而不是 char*
。
示例
int size = 35;
// malloc size for text
char *txt = malloc((size+1) * sizeof(char ));
if(!txt) {
fprintf(stderr, "Allocation for text data failed.\n");
return EXIT_FAILURE;
}
memset(txt,0,size+1);
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
printf("%s\n", txt);
free(txt);
txt=NULL;
- 或者也可以设置
txt[size]='[=17=]'
因为所有其他位置都被输入的字符覆盖。 [彼得对此发表了评论]
char *txt = malloc(size + 1);
...
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
txt[size] = '[=10=]';
printf("%s\n", txt);
int size = 35;
// malloc size for text
char *txt = malloc(size * sizeof(char *));
您没有分配 35 个字节,而是分配了 35 个指针(即 32 位上的 140 个字节或 64 位上的 280 个字节)。
这应该是 'malloc(size * sizeof(char))' 或者只是 malloc(size).
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
您只初始化了分配的 140 或 280 个字节中的前 35 个。
你没有用 null 终止你的字符串。
printf("%s\n", txt);
现在您正在打印一个非空终止字符串和 valgrind
已正确警告您它正在访问未初始化的内存
尝试对输入文本执行 strlen()。
我的问题很简单,我不明白为什么这个程序不能正确输出:
int size = 35;
// malloc size for text
char *txt = malloc(size * sizeof(char *));
if(!txt) {
fprintf(stderr, "Allocation for text data failed.\n");
return EXIT_FAILURE;
}
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
printf("%s\n", txt);
free(txt);
预期输出:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
实际输出:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8 9 10 1 0 12 11 6 37 44 3 45 56 0 64 77 5 68 83 0 39 46 0 19 16 9 8 2 6 3 1 4 17 12 9 17 6 0 25 10 3 31 16 13 21 9 9 11 7 4 2 3 0 7 6 1 9 5 2 11 2 5 19 6 13 21 8 15 8 0 0 7 0 0 29 20 13 62 50 0 49 35 0 41 27 1 38 25 9 25 13 0 21 11 0 24
尝试使用 valgrind --leak-check=yes
调试 ,它显示的唯一错误如下:
==3999== Conditional jump or move depends on uninitialised value(s)
==3999== at 0x4C30F78: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3999== by 0x4EA969B: puts (ioputs.c:35)
==3999== by 0x400B39: main (decode.c:85) // this is the printf line
我以为是不知道什么时候停止打印,结果试了:
while(txt != NULL) {
printf("%c", *(txt++));
}
我也试过了:
txt[size - 1] = '[=12=]';
while((*txt) != '[=12=]') {
printf("%c", *(txt++));
}
那些会产生更糟糕的结果,因为它会用特殊字符填充我的控制台。
将 [=11=]
放入 char 数组中。否则 printf
将有 undefined behavior
.
同样在 malloc
中,您分配给 char
而不是 char*
。
示例
int size = 35;
// malloc size for text
char *txt = malloc((size+1) * sizeof(char ));
if(!txt) {
fprintf(stderr, "Allocation for text data failed.\n");
return EXIT_FAILURE;
}
memset(txt,0,size+1);
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
printf("%s\n", txt);
free(txt);
txt=NULL;
- 或者也可以设置
txt[size]='[=17=]'
因为所有其他位置都被输入的字符覆盖。 [彼得对此发表了评论]
char *txt = malloc(size + 1);
...
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
txt[size] = '[=10=]';
printf("%s\n", txt);
int size = 35;
// malloc size for text
char *txt = malloc(size * sizeof(char *));
您没有分配 35 个字节,而是分配了 35 个指针(即 32 位上的 140 个字节或 64 位上的 280 个字节)。
这应该是 'malloc(size * sizeof(char))' 或者只是 malloc(size).
for(int i = 0; i < size; i++) { // for each character in text
txt[i] = 'a';
}
您只初始化了分配的 140 或 280 个字节中的前 35 个。 你没有用 null 终止你的字符串。
printf("%s\n", txt);
现在您正在打印一个非空终止字符串和 valgrind 已正确警告您它正在访问未初始化的内存 尝试对输入文本执行 strlen()。