Space pointed to with malloc () is not released with free ()

2

In the following code; in the loop the value of ncrC-> count varies because the pointer does not restart when using free (s) and does not locate as it is due to loop the string: "Counter=". Please help.

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

#define MAXUSE 1000
#define TAGSIZE 4
#define MAXBUF 100

struct ncrcode                                 /* Structure of ncrcode  */
{
    int count;
                                
};


int main()
{
    int q = 1, i = 0, x=0, a=0;
    char ch;
    
    FILE * fp;
    
    struct ncrcode *ncrC;
    
    ncrC = (struct ncrcode *) malloc(sizeof(*ncrC));    /* gets room for the new node */
    
    
    while (q)
    {
        /* This .txt file contains a file reference to another file */
        fp = fopen("nd0_1.txt", "r");
        
        char *s = (char *)malloc(sizeof(char)*20);
        
        /* 1 - Get COUNTER getnodecounter() */
        
        while( (ch = fgetc(fp)) != EOF)
        {
            s[i++] = ch;
            
            if (strcmp(s,"Counter = ") == 0)
            {
                printf("\nPLAKAPLAKA%d", a++);
                break;
            }
        }
        i = 0;
        printf("\n First\n%d\n",ncrC->count = 0);
        while( (ch = fgetc(fp)) != '\n')
        {
            printf("%c\n", ch);
            ncrC->count = (ch - 48) + ( ncrC->count * 10);
        }
        
        printf("\n STRINNNN \n%d\n",ncrC->count);
        
        free(s);
        fclose(fp);
    }
    return (0);
    
asked by Ivan Soler 21.05.2017 в 00:19
source

1 answer

2

free() is correctly releasing the memory. 1

What does not fit you is that malloc , when allocating memory, does not initialize . It gives you a pointer to memory and the "garbage" that is there is maintained.

In your case it seems that the memory manager releases s and, when you ask for the same amount of memory again, it gives you the same position (which is now available) 2 . If you did not free the memory, malloc would return a pointer to any other zone , and not to it.

The real problem is reading the file. Your code goes character by character assigning to the array, but the problem is that when you finish reading the characters you do not put the termination value of string ( strcmp ). Therefore, any strings function ( strcpy , string , etc.) will continue reading beyond the characters you have assigned until you find a calloc .

Solution. Two options:

  • The correct one for this case is that, after reading the file, assign malloc to finish the 0 . Looking at your code, I would:

    s[i++] = ch;
    s[i] = (char) 0;  // En cada iteración "terminas" la cadena para poder
                      // usar strcmp. Si iteras otra vez, el 0 se sobreescribirá
                      // con el siguiente caracter.
    if (strcmp....
    
  • And more related to memory management, you can call malloc instead of string ; what it does is that apart from assigning you the memory you initialize it all to s .

It should also be noted that being continuously requesting and releasing memory is very inefficient. If you do not keep a permanent reference to the memory, it would be much better to do malloc before starting the loop and release it later. As long as you remember to put the %code% to end the %code% , there will be no problem with reusing the same area. Naturally, once you're done, you can only apply the first solution.

1 A simple test. Although releasing a pointer twice means "undefined behavior" and in theory anything can happen, in my experience it almost always means an abrupt termination of the program. You can do the experiment of releasing twice %code% and check that, possibly, the program suffers a crash.

2 As far as I know, %code% is free to return any pointer; that you return the same depends on the implementation.

    
answered by 21.05.2017 / 12:08
source