views:

63

answers:

4

I'm having problems understanding why following code leaks in one case, and not in the other case. The difference is

while(NULL!=fgets(buffer,length,file))//doesnt leak
while(NULL!=(buffer=fgets(buffer,length,file))//leaks

I thought it would be the same.

Full code below.

#include <stdio.h>
#include <stdlib.h>

#define LENS 10000

void no_leak(const char* argv){
  char *buffer = (char *) malloc(LENS);
  FILE *fp=fopen(argv,"r");

  while(NULL!=fgets(buffer,LENS,fp)){
    fprintf(stderr,"%s",buffer);

  }
  fclose(fp);
  fprintf(stderr,"%s\n",buffer);
  free(buffer);  


}
void with_leak(const char* argv){
  char *buffer = (char *) malloc(LENS);
  FILE *fp=fopen(argv,"r");

  while(NULL!=(buffer=fgets(buffer,LENS,fp))){
    fprintf(stderr,"%s",buffer);

  }
  fclose(fp);
  fprintf(stderr,"%s\n",buffer);
  free(buffer);  


}
+5  A: 

Because you are reassigning what buffer used to point to. By the time you get to the free(buffer); at the end of the code, buffer would be pointing to NULL (because that's what you tested for to get out the while loop) and hence when you call free, you're not calling it on the original pointer you malloc'd, you're calling it on nothing.

Salgar
+1  A: 

On successful reading, it will be fine. But when end of file is reached, fgets will return NULL and thus buffer will be NULL and you won't be able to free it.

shinkou
+1  A: 

You will get a leak when fgets returns NULL. It's legal to call free on a NULL pointer but of course by this point you have lost your original pointer.

Paul R
+1  A: 

If fgets() returns NULL, buffer loses it's original value so you no longer can free it.

qrdl