问题描述
我有以下ANSI C代码:
I have the following ANSI C code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *buffer = 0;
int length = 0;
FILE *f = fopen("text.txt", "r");
if(f) {
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
buffer = malloc(length);
fread(buffer, 1, length, f);
fclose (f);
}
printf("File size: %d\nBuffer size: %d\nContent: %s\n=END=", length, strlen(buffer), buffer);
return 0;
}
由于某种原因,malloc分配了比所需更多的内存,并从内存中输出了额外的垃圾,例如:第一次运行:
Which for some reason after the malloc alocates more memory than needed and output extra garbage from the memory, example:First run:
File size: 12
Buffer size: 22
Content: 123456789012les=$#▬rW|
=END=
第二次运行:
File size: 12
Buffer size: 22
Content: 123456789012les↔1↕.'
=END=
第三次运行:
File size: 12
Buffer size: 22
Content: 123456789012les=▬kπà
=END=
有人可以帮我这个忙,还可以解释为什么我的版本很奇怪吗?我使用MingW TDM-GCC 4.9.2 32bit进行编译(gcc)
Could someone please help me with this and also explain why my version is behaving weird?I use MingW TDM-GCC 4.9.2 32bit for compilation (gcc)
推荐答案
您有不确定的行为(此解释了为什么您应该害怕UB)-因为缓冲区溢出.您忘了添加一个终止的空字节.
You have undefined behavior (this explains why you should be afraid of UB) -because of buffer overflow. You forgot to add a terminating null byte.
替换有问题的行:
// WRONG CODE:
buffer = malloc(length);
fread(buffer, 1, length, f);
使用
buffer = malloc(length+1);
if (!buffer)
{ perror("malloc"); exit(EXIT_FAILURE); };
memset (buffer, 0, length+1);
if (fread(buffer, 1, length, f) < length)
{ perror("fread"); exit(EXIT_FAILURE); };
顺便说一句,ANSI C已过时.您应该使用 C11 兼容的编译器(例如, recent GCC 用作gcc -std=c11 -Wall -Wextra -g
)并达到C11规范(或至少 C99 ).学习使用调试器(例如 gdb
)
BTW, ANSI C is obsolete. You should use a C11 compliant compiler (e.g. a recent GCC used as gcc -std=c11 -Wall -Wextra -g
) and target C11 compliance (or at least C99). Learn to use the debugger (e.g. gdb
)
请仔细阅读 malloc(3)的文档, fread(3), perror(3)等.
Read carefully the documentation of malloc(3), fread(3), perror(3) etc....
这篇关于C中奇怪的malloc行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!