Malloc'd char数组具有意外输出

时间:2017-10-29 03:58:43

标签: c printf malloc valgrind

我的问题很简单,我不明白为什么这个程序输出不正确:

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

实际输出:

  

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 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 ==条件跳转或移动取决于未初始化的值(s)
  == 3999 ==在0x4C30F78:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  == 3999 == by 0x4EA969B:puts(ioputs.c:35)
  == 3999 == by 0x400B39:main(decode.c:85)//这是printf行

我以为是因为它不知道何时停止打印,但我试过了:

while(txt != NULL) {
    printf("%c", *(txt++));
}

我也尝试过:

txt[size - 1] = '\0';

while((*txt) != '\0') {
    printf("%c", *(txt++));
}

那些会给我的控制台填充特殊字符的结果更糟糕。

3 个答案:

答案 0 :(得分:3)

\0放入char数组中。否则printfundefined 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;
  1. 或者,也可以设置txt[size]='\0'因为所有其他位置都被输入的字符覆盖。 [彼得评论了这个]

答案 1 :(得分:1)

int size = 35;
// malloc size for text
char *txt = malloc(size * sizeof(char *));

你没有malloc&#39; 35个字节,而是35个指针(即32位140个字节或64位280个字节)。

这应该是&#39; malloc(size * sizeof(char))&#39;或者只是malloc(大小)。

for(int i = 0; i < size; i++) { // for each character in text
    txt[i] = 'a';
}

您只初始化了分配的140或280个字节中的前35个。 你没有终止你的字符串。

printf("%s\n", txt);

现在您正在打印一个不会被终止的字符串和valgrind 已正确警告您,它正在访问未初始化的内存时 试图在输入txt上执行strlen()。

答案 2 :(得分:0)

char *txt = malloc(size + 1); ...

for(int i = 0; i < size; i++) { // for each character in text
    txt[i] = 'a';
}
txt[size] = '\0';
printf("%s\n", txt);