Amous
Amous

Reputation: 514

Does a memory leak exist?

I'm looking at an assignment question. With it there is this piece of C code:

char* read_from_file (const char* filename, size_t length) {
    return NULL;
}

void main (int argc, char **argv) {
    char* buff;
    if ((buff = read_from_file("test1.txt", 10)) == NULL) {
       fprintf(stdout, "Failed to read test1.txt\n");
    } else {
       fprintf(stdout, "buff is: %s\n", buff);
    }
    if ((buff = read_from_file("test2.txt", 10)) == NULL) {
       fprintf(stdout, "Failed to read test2.txt\n");
    } else {
       fprintf(stdout, "buff is: %s\n", buff);
    }
}

The question says that memory is leaking. It tells me to insert free(buff) statements in the main program to suppress memory leaking. I always thought that memory leaks were normally associated with dynamic memory allocation. As well, shouldn't free() be used to free a pointer to a memory block previously allocated with malloc(), etc.

Is there something I'm missing with this assignment question?

NOTE: I'm just looking for advice and insights.

Upvotes: 0

Views: 140

Answers (2)

Kaz
Kaz

Reputation: 58647

This program can be completed such that read_from_file actually reads from the file into a buffer and returns it, yet such that there are no leaks. Moreover, that buffer can be dynamic. Moreover, the main function need not be modified! Here is a sketch:

static char *read_from_file_buf;

void read_from_file_cleanup(void)
{
  free(read_from_file_buf);
}

char *read_from_file(const char* filename, size_t length)
{
  static int inited;
  char *new_buf;

  if (!inited) {
    atexit(read_from_file_cleanup);
    inited = 1;
  }

  if ((new_buf = realloc(read_from_file_buf, length)) != NULL) {
    read_from_file_buf = new_buf;
    /* open file, fill in buf */
    return new_buf;
  }

  return NULL;
}

This implementation of read_from_file can only be used if a severe restriction is observed. When you call it the second time, it destroys the data which it allocated and returned on the first call! Woe to the program if it keeps trying to use that data. But: the given main is structured such that it meets this usage restriction.

Only one buffer exists at a time and the registered atexit handler ensures that it is freed when the program terminates. (Omitting this handler would be fine in "mainstream" computing environments in which C programs are mapped to processes that are reliably cleaned up on exit. Applications in such environments can neglect to free their "singleton" objects.)

Upvotes: 0

user149341
user149341

Reputation:

There is definitely something missing here. There are no memory allocations made in this program -- the only standard library function it calls is fprintf, which doesn't allocate memory (outside of internal bookkeeping that isn't visible to the caller). As such, it can't leak memory.

Is it possible that you're supposed to be working with a different definition of the read_from_file function? A simple implementation along the lines of:

char* read_from_file (const char* filename, size_t length) {
    char *buff = malloc(length);
    open the file, read some data into buff, close it
    return buff;
}

would cause your program to leak memory when used in the way shown in your main.

Upvotes: 1

Related Questions