1

I am currently working on a piece of code where we are parsing a file and working with different functions. Through debugging with printf calls, I have found that I am getting a memory error on the second malloc call. What could cause the second malloc to fail in this rough skeleton?

struct example {
    char *myChar;
    int myInt;
};

struct example *doThing(FILE *file) {
    struct example *myToken = (struct example *)malloc(sizeof(struct example));
    char buffer[32] = "";

    // other stuff

    if (strncmp(buffer, "random", 6) == 0) {
        strncpy(myToken->myChar, buffer, 6);
        myToken->tokenid = 1;
        return myToken;
    }

    return NULL; 
}

struct example *doThing2(FILE *file) {
    struct example *myOtherToken = (struct example *)malloc(sizeof(struct example));
    // other stuff
    return myOtherToken;
}

int main() {
    FILE *ofp = fopen("thefile.txt", "r");
    struct example *token1, *token2;

    token1 = doThing(ofp);
    token2 = doThing2(ofp);

    // other stuff

    free(token1);
    free(token2);
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Tyler Dunn
  • 11
  • 2
  • 2
    Because of the `// other stuff` – Eugene Sh. Sep 23 '19 at 20:18
  • Unrelated but: https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Mat Sep 23 '19 at 20:20
  • That's 100% because of stuff you omitted in your snippet. The code you posted looks perfectly fine (you should also `fclose(ofp)`, but whatever). – Marco Bonelli Sep 23 '19 at 20:21
  • Also, for a `malloc` to fail your program would have to perform some really catastrophic stuff... it's probably something else that is failing, not `malloc` itself. – Marco Bonelli Sep 23 '19 at 20:23
  • Alright, I've added on some more stuff. The code will get through the first function fine, and then a print function will print immediately before the second malloc but not after the second malloc – Tyler Dunn Sep 23 '19 at 20:25
  • 2
    As for the edit - `strncpy(myToken ->myChar, buffer, 6);` - you are copying into unallocated space (or you have not shown us any allocation). – Eugene Sh. Sep 23 '19 at 20:26
  • 3
    `strncpy(myToken ->myChar` - you haven't allocated space for `myChar` (or you're not showing it). [mcve] please. – Mat Sep 23 '19 at 20:26
  • You should really first check if the code makes sense instead of stripping down everything to make it minimal. – Marco Bonelli Sep 23 '19 at 20:34
  • *What could cause the second malloc to fail?* Something you did wrong with the memory you got back from the first malloc, generally either (a) writing past the end of the block, (b) writing before the beginning of the block, or (c) freeing it twice. – Steve Summit Sep 23 '19 at 20:49
  • OT: regarding `FILE *ofp = fopen("thefile.txt", "r");` when calling `fopen()`, always check (!=NULL) the returned value to assure the operation was successful. If not successful, call `perror( "fopen failed" );` then cleanup and exit the program. – user3629249 Sep 24 '19 at 16:49
  • OT: regarding this kind of statement: `struct example *myOtherToken = (struct example *) malloc(sizeof(struct example));` 1) the returned type is `void*` which can be assigned to any pointer. casting just clutters the code, making it more difficult to understand, debug, etc. 2) when calling any of the heap allocation functions: `malloc()` `calloc()` `realloc()`, always check (!=NULL) the returned value. If == NULL, then call `perror( "malloc failed" ); then clean up and exit the program. – user3629249 Sep 24 '19 at 16:52

1 Answers1

2

You are facing memory leak. correct your code folowing one of the two samples bellow

and yes, as @Eugene_Sh mentioned, you should allocate memory for myToken->myChar and do not forget to free it before freeing myToken

SAMPLE 1
struct example* doThing(FILE *file) {

    char buffer[32] = "";

    // other stuff

    if (strncmp(buffer, "random", 6) == 0) {

        struct example *myToken = (struct example *) malloc(sizeof(struct example));

        myToken ->myChar= malloc(7);
        strncpy(myToken ->myChar, buffer, 6);
        myToken ->myChar[6]=0;
        myToken->tokenid = 1;
        return myToken;
    }

    return NULL; 
}
SAMPLE 2
struct example* doThing(FILE *file) {
    struct example *myToken = (struct example *) malloc(sizeof(struct example));
    char buffer[32] = "";

    // other stuff

    if (strncmp(buffer, "random", 6) == 0) {


        myToken ->myChar= malloc(7);
        strncpy(myToken ->myChar, buffer, 6);
        myToken ->myChar[6]=0;
        myToken->tokenid = 1;
        return myToken;
    }
    free(myToken );
    return NULL; 
}
milevyo
  • 2,165
  • 1
  • 13
  • 18