-3

Not sure what is wrong with the code below and why it is giving me the error "pointer being freed was not allocated". Using clang.

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

static char * messagePtr;

int main()
{

    messagePtr = (char *)malloc(sizeof(char) * 800);
    if(messagePtr == NULL) {
       printf("Bad malloc error\n");
       exit(1);
    }


    // //gameLoop();
    char outputMessage[50] = "";
    messagePtr = outputMessage;

    free(messagePtr);
    messagePtr = NULL;

    return 0;
}
Steven2163712
  • 169
  • 2
  • 12
  • 6
    `messagePtr = outputMessage;` = no longer pointing to the (now leaked) dynamic memory you allocated earlier. If you don't see that, you need to review the section on dynamic memory management in whatever book or tutorial you're using. – WhozCraig Jul 23 '16 at 09:52
  • 2
    You do not need the cast for `malloc` in C - better it is removed – Ed Heal Jul 23 '16 at 09:53
  • 2
    Keep that in mind: You don't "free a pointer", you free the memory it **points to**! (I'd really like to have a serious talk with teachers who spread such nonsense - would greatly reduce confusion) – too honest for this site Jul 23 '16 at 10:26

3 Answers3

3

The lines

char outputMessage[50] = "";
messagePtr = outputMessage;

create a char[50] and assign messagePtr the address of that array, thus removing the pointer to the malloced memory. The successive free call therefore tries to free messagePtr, not the memory allocated by malloc. Not only this, the mallocated memory will be lost since you have lost all reference (i.e., the pointer) to it.

I'm not entirely sure what you are trying to accomplish by messagePtr = outputMessage, so I can't really give you a hint on solving this - except to not reassign a pointer returned by malloc prior to freeing it.


Notes:

Community
  • 1
  • 1
cadaniluk
  • 15,027
  • 2
  • 39
  • 67
3

You assigned outputMessage, which is an array and is converted to a pointer to the first element of the array, to messagePtr, so messagePtr no longer points at what is allcated via malloc() or its family.

Passing what is not NULL and is not allocated via memory management functions such as malloc() invokes undefined behavior. (N1570 7.22.3.3 The free function)

Note that they say you shouldn't cast the result of malloc() in C.

Some of your options are:

1. Stop using malloc() for allocating buffer that will be thrown away.

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

static char * messagePtr;

int main()
{

    // //gameLoop();
    char outputMessage[50] = "";
    messagePtr = outputMessage;

    messagePtr = NULL;

    return 0;
}

2. Free the buffer before throwing it away.

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

static char * messagePtr;

int main()
{

    messagePtr = malloc(sizeof(char) * 800);
    if(messagePtr == NULL) {
       printf("Bad malloc error\n");
       exit(1);
    }


    // //gameLoop();
    free(messagePtr);
    char outputMessage[50] = "";
    messagePtr = outputMessage;

    messagePtr = NULL;

    return 0;
}

3. Use strcpy() to copy strings.

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

static char * messagePtr;

int main()
{

    messagePtr = malloc(sizeof(char) * 800);
    if(messagePtr == NULL) {
       printf("Bad malloc error\n");
       exit(1);
    }


    // //gameLoop();
    char outputMessage[50] = "";
    strcpy(messagePtr, outputMessage);

    free(messagePtr);
    messagePtr = NULL;

    return 0;
}
Community
  • 1
  • 1
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • strcpy() was the function that I was looking for. I had looked at a lot of tutorials, searched a lot on the web and here and figured that the solution was probably simple, I just wasn't finding it. Thank you everyone for your answers. – Steven2163712 Jul 23 '16 at 16:41
0
messagePtr = (char *)malloc(sizeof(char) * 800);

makes messagePtr pointing to the location in Heap where malloc allocated 800 chars (e.g. 1005). This location has to be freed.

messagePtr = outputMessage;

makes messagePtr pointing to the location in Stack where 50 chars where automatically allocated (e.g. 505).

Automatic allocations can not be freed with free. They are deallocated automatically when the variable's scope ends. Calling free on the automatically allocated memory is an error. free has to be called on location 1005 (according to the example).