简体   繁体   English

Malloc的char数组具有意外的输出

[英]Malloc'd char array has unexpected output

My problem is simple, I don't understand why this program doesn't output correctly : 我的问题很简单, 我不明白为什么该程序无法正确输出:

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);

Expected output : 预期产量:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Actual output : 实际输出:

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 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8 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


Tried debugging with valgrind --leak-check=yes , the only error it shows is the following : 使用valgrind --leak-check=yes 尝试调试 ,它显示的唯一错误如下:

==3999== Conditional jump or move depends on uninitialised value(s) == 3999 ==条件跳转或移动取决于未初始化的值
==3999== at 0x4C30F78: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) == 3999 ==在0x4C30F78:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3999== by 0x4EA969B: puts (ioputs.c:35) == 3999 ==通过0x4EA969B:看跌期权(ioputs.c:35)
==3999== by 0x400B39: main (decode.c:85) // this is the printf line == 3999 ==通过0x400B39:main(decode.c:85)//这是printf行

I thought it was because it didn't know when to stop printing, but I tried : 我以为是因为它不知道何时停止打印,但是我尝试了:

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

And I also tried : 我也尝试过:

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

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

Those gave even worse results where it would fill my console with special characters. 在给我的控制台添加特殊字符的地方,结果甚至更糟。

Put the \\0 in the char array. \\0放入char数组。 Otherwise printf will have undefined behavior . 否则, printf将具有undefined behavior

Also in malloc you are allocating for char not char* . 同样在malloc您正在分配char而不是char*

Example

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. Alternatively one can set txt[size]='\\0' also because all other position are overwritten with characters inputted. 另外,也可以设置txt[size]='\\0'因为所有其他位置都被输入的字符覆盖。 [ Peter commented this] [ 彼得对此评论]
int size = 35;
// malloc size for text
char *txt = malloc(size * sizeof(char *));

You have not malloc'ed 35 bytes, but instead 35 pointers (ie 140 bytes on 32-bit or 280 bytes on 64-bit). 您尚未分配35个字节,而是分配了35个指针(即32位为140字节或64位为280字节)。

This should be 'malloc(size * sizeof(char))' or just malloc(size). 这应该是'malloc(size * sizeof(char))'或仅仅是malloc(size)。

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

You've initialized only the first 35 of 140 or 280 bytes allocated. 您仅初始化了分配的140或280字节中的前35个字节。 You haven't null terminated your string. 您还没有null终止您的字符串。

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

Now you are printing a string that isn't null terminated and valgrind has correctly warned you that it is accessing uninitialized memory when trying to perform strlen() on the input txt. 现在,您正在打印一个不以null结尾的字符串,并且valgrind已正确警告您在尝试对输入txt执行strlen()时,它正在访问未初始化的内存。

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM