Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
274 views
in Technique[技术] by (71.8m points)

weird malloc behavior in 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
Buffer size: %d
Content: %s
=END=", length, strlen(buffer), buffer);
    return 0;
}

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=

Second run:

File size: 12
Buffer size: 22
Content: 123456789012les?1?.'
=END=

Third run:

File size: 12
Buffer size: 22
Content: 123456789012les=?kπà
=END=

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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

Replace the faulty lines:

    // WRONG CODE:
    buffer = malloc(length);
    fread(buffer, 1, length, f);

with

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

(You could zero just the ending byte; I prefer to clear with memset the entire buffer)

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)

Read carefully the documentation of malloc(3), fread(3), perror(3) etc....


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...