简体   繁体   中英

Free char pointer in C language

I have the following function which reads in the graph. When I am running Valgrind I am getting following error:

definitely lost: 1,048,576 bytes in 1 blocks

I am allocating 1048576 bytes using char * line = malloc(1024 * 1024) but in the end, I am freeing line pointer. What am I doing wrong here?

pr_graph * pr_graph_load(
char const * const ifname)
{
 FILE * fin = fopen(ifname, "r");
 pr_graph * graph = malloc(sizeof(*graph));

 char * line = malloc(1024 * 1024);
 size_t len = 0;

 /* Read in graph one vertex at a time. */
 for(pr_int v=0; v < graph->nvtxs; ++v) {
ssize_t read = getline(&line, &len, fin);
if(read == -1) {
  free(line);
  fprintf(stderr, "ERROR: premature EOF at line %lu\n", v+1);
  pr_graph_free(graph);
  return NULL;
}

/* Store the beginning of the adjacency list. */
graph->xadj[v] = edge_ptr;

/* Check for sinks -- these make pagerank more difficult. */
if(read == 1) {
  fprintf(stderr, "WARNING: vertex '%lu' is a sink vertex.\n", v+1);
  continue;
}

/* Foreach edge in line. */
char * ptr = strtok(line, " ");
while(ptr != NULL) {
  char *end = NULL;
  pr_int const e_id = strtoull(ptr, &end, 10);
  /* end of line */
  if (ptr == end) {
    break;
  }
  assert(e_id > 0 && e_id <= graph->nvtxs);

  graph->nbrs[edge_ptr++] = e_id - 1; /* 1 indexed */
  ptr = strtok(NULL, " ");
}
 }
 assert(edge_ptr == graph->nedges);
 graph->xadj[graph->nvtxs] = graph->nedges;

 free(line);
 fclose(fin);

 return graph;

You are misusing the POSIX getline() function. You have:

char * line = malloc(1024 * 1024);
size_t len = 0;

/* Read in graph one vertex at a time. */
for(pr_int v=0; v < graph->nvtxs; ++v)
{
    ssize_t read = getline(&line, &len, fin);

You tell getline() there are zero bytes allocated, so it allocates more space in line — it is under no obligation to free() line before doing so.

 ssize_t getline(char **restrict lineptr, size_t *restrict n, FILE *restrict stream); 

The application shall ensure that *lineptr is a valid argument that could be passed to the free() function. If *n is non-zero, the application shall ensure that *lineptr either points to an object of size at least *n bytes, or is a null pointer.

Your code meets the ' *lineptr is a valid argument that could be passed to free() ' criterion; but you set *n to zero so the second condition isn't relevant. Since *n says "there is no memory allocated yet", it will ignore the value in *lineptr .

You should be using one of these:

char * line = 0;
size_t len = 0;

/* Read in graph one vertex at a time. */
for(pr_int v=0; v < graph->nvtxs; ++v)
{
    ssize_t read = getline(&line, &len, fin);

or:

size_t len = 1024 * 1024;
char * line = malloc(size);

/* Read in graph one vertex at a time. */
for(pr_int v=0; v < graph->nvtxs; ++v)
{
    ssize_t read = getline(&line, &len, fin);

Either will work. I'd probably use the empty buffer — I don't often allocate 1 MiB of space up front unless I know it will all be used.

Be aware that with the null pointer and zero length, getline() will typically allocate space even if the file is empty and it immediately returns -1 . You should take steps to free it. Since line is null, even if getline() doesn't allocate space, line can be passed to free() safely.

If you are compiling correctly (compile and link with the -g option), Valgrind will tell you which line allocated the leaked memory. If you don't get that information, you are misusing Valgrind (or, at least, under-using it — it can tell you so much more if you let it).

I think you should try to disable this line

ssize_t read = getline(&line, &len, fin);

It is a guess, but I think that line is being modified by getline ...

so if you run the code without it then you will see with valgrind if that is where the problem lies.

If that is the answer is there anyway you can have a smaller amount of memory for line and define it with

char line [100000];

then you wouldn't have the same memory issue I think...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM