I’m getting “malloc: * error for object 0xbfffe160: pointer being freed was not allocated” when trying to free memory (in objective-c code) of an object that was allocated inside c function. This C function creates and returns binary data packet that is used as NSData later. Here’s my obj-c code part where I’m creating struct variable and passing it by reference to C function:
MyPacket packetRef;
allocAuthentificationCodePacket(&packetRef);
NSData *data = [NSData dataWithBytes:packetRef.bytes length:packetRef.packet->packetSize];
free(&packetRef); // getting error
Everything work fine, except I’m trying to release the memory because the data should be retained by NSData variable. The C functions performs calloc inside itself, so I should somehow to release that memory:
packetRef->bytes = calloc(1, sizeof(*packetRef));
Here’s are my structs for storing binary data:
typedef struct {
uint8_t packetType;
uint16_t packetBody;
} MyStruct;
and another struct:
typedef union {
const uint8_t *bytes;
MyStruct *packet;
} MyPacket;
How should I free the memory? The error I’m getting is not crash, it just a message in debug console when running unit tests.
UPDATE. Tried to release “bytes” struct member but getting the same error message:
free(&packetRef.bytes);
UPDATE2. Thanks, the suggested way did worked and malloc error message disappeared from console:
free(packetRef.bytes);
However, getting a warning in Xcode “Passing ‘const uint8_t *’ (aka ‘const unsigned char *’) to parameter of type ‘void *’ discards qualifiers”. I’m using Apple LLVM 4.1 compiler. C function resides in separate file and only a header is included because Android guys will have to reuse it.
UPDATE3. Thanks to @simonc and @nos who have pointed out the struct member “bytes” has const. The warning has disappeared after removing const. The initial idea of using const was to protect “bytes” from modification.
This is always wrong. (Hint: It’s almost always wrong to put
&inside offree().)It doesn’t matter what
MyPacketis — it has automatic storage duration, i.e., the compiler automatically allocates storage and frees it when the function exits.Do not
free()something unless it came frommalloc()(orcalloc(), etc.)Since
packetRef.byteswas allocated withcalloc(), you canfree()that instead.Update
If the function that you call,
allocAuthentificationCodePacket, contains the code:And if the
bytesfield has typeconst uint8_t *, then something is wrong.Perhaps your code is wrong, and you are supposed to call some function to free the packet rather than freeing it yourself.
Perhaps the type of the
bytesfield is wrong, and should beuint8_t *instead ofconst uint8_t *.Perhaps
allocAuthentificationCodePacketis wrong.Who knows? It’s not wrong enough to crash, but it is a problem.
Footnote
There are no references in C.
&xis “address of x”, not “reference to x”.Let’s consider the following code:
When people talk about this code, they will say something like “
xis allocated on the heap”, but that’s not technically correct,xis allocated on the stack and contains the address of 10 bytes on the heap. Likewise, the linefree(x)does not actually freex, it frees the memory whichxpoints to.So when someone tells you, “don’t forget to free
x“, you know they actually mean “don’t forget to free the memory which the value contained inxpoints to”. People are sloppy with terminology but computers aren’t.