tags:

views:

3008

answers:

6

I often use the website www.cplusplus.com as a reference when writing C code.

I was reading the example cited on the page for fread and had a question.

As an example they post:

/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>

int main () {
  FILE * pFile;
  long lSize;
  char * buffer;
  size_t result;

  pFile = fopen ( "myfile.bin" , "rb" );
  if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (char*) malloc (sizeof(char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);
  if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

  /* the whole file is now loaded in the memory buffer. */

  // terminate
  fclose (pFile);
  free (buffer);
  return 0;
}

It seems to me that that if result != lSize, then free(buffer) will never get called. Would this be a memory leak in this example?

I have always thought the examples on their site are of a very high quality. Perhaps I am not understanding correctly?

A: 

The operating system cleans up any unfreed memory by a process when that process closes. At least, modern operating systems do.

strager
A: 

If the program were not exiting at the point result != lSize, that is, it continued with some other path of execution, then yes - it is a guaranteed memory leak.

Sandeep
+3  A: 

Technically, yes it is a memory leak. But any memory allocated by a process is automatically freed when that process terminates, so in this example the calls to free (and fclose) are not really required.

In a more complex program, this would probably be a real problem. The missing free would create a memory leak and the missing fclose would cause a resource leak.

Ferruccio
+3  A: 

It wouldn't be a memory leak in this example, because terminating the program (by calling exit()) frees all memory associated with it.

However, it would be a memory leak if you used this piece of code as a subroutine and called something like return 1; in place of exit().

jpalecek
A: 

There are two possible paths.

(1) result != lSize - in this case, exit(0) is called. This kills the process and the operating system will clean up the memory.

(2) result == lsize - in this case, the buffer is explicitly freed, but return is called right afterwards so the free is mostly just good style because this also kills the process and the operating system will, again, clean up the memory.

So in this simple case, there is no memory leak. But it is probably a good practice to just make sure you're freeing any memory you've allocated in any application you write. Getting into this habit will prevent many headaches for you in the future.

A: 

As to possible memory leakage, other's have already answered that question. A while ago, I posted a variation of the given code which should handle all possible error conditions correctly:

Christoph