Malloc of 2 bytes gives problems
I am trying to use shortall malloc, something like
typedef union _SOME_STRUCT_ {
struct {
USHORT u:4;
USHORT v:4;
USHORT w:4;
} x;
USHORT word;
} SOME_STRUCT, *PSOME_STRUCT;
PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));
if (p) {
p->x.u = 0;
}
free (p); // **** RANDOMLY CRASHING HERE ****
I've been debugging for a couple of days and I don't know
Note (edited): Linux and gcc Version 3.4.6 20060404
ISSUE FOUND USING VALGRIND
But then I would like to document it here so that my fellow developers can be aware of such a situation ...
I actually defined the structure as
typedef union _SOME_STRUCT_ {
struct {
USHORT u:4;
USHORT v:4;
USHORT w:4;
} x;
USHORT word;
} ALBUM, *PALBUM;
and somewhere else in the code that I also defined
#define ALBUM "album"
So sizeof (ALBUM) was referring to the #define value, not the typedef and hence the problem.
What amazes me is
Is this allowed in C?
a source to share
This version of the code works for me.
#include <stdio.h>
#define USHORT unsigned short
typedef union _SOME_STRUCT_ {
struct {
USHORT u:4;
USHORT v:4;
USHORT w:4;
} x;
USHORT word;
} SOME_STRUCT, *PSOME_STRUCT;
int
main(int c, char *argv[])
{
PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));
if (p) {
p->x.u = 0;
}
free (p); // **** Properly exiting after this ****
}
This is GDB debugging from Cygwin on Windows XP.
(gdb) p/x sizeof(PSOME_STRUCT)
$1 = 0x4
(gdb) p/x sizeof(p)
$2 = 0x4
(gdb) p/x sizeof(*p)
$3 = 0x2
(gdb) n
23 if (p) {
(gdb) p/x *p
$4 = {x = {u = 0xc, v = 0x4, w = 0x3}, word = 0x534c}
Ignore values in $ 4, data is not initialized. The program came out fine.
Do you have anything else in your code besides these lines?
Edit: and, free (0); is a valid operation.
a source to share
The problem is not with the code, but with what happens before or in a different thread.
I would shorten the sections of the program until it stops crashing, then add it back step by step until I figure out which section is causing this. Depending on OS / platform, you can also try some memory checking tools, valgrind / _crtdebug, etc.
a source to share
You call free () unconditionally without checking if malloc succeeded, so if malloc failed and p is a NULL pointer, then you call free (NULL).
Move the free space inside the if (p) block.
This may not be the cause of the crashes, and should not be unless limited by memory, but is a bug nonetheless.
Added later: doh, free (NULL) is explicitly allowed, per http://www.opengroup.org/onlinepubs/009695399/functions/free.html - sorry.
a source to share
If you do stuff between malloc and free you could accidentally fool another array and damage your own stack
(if "p" is not in register and you overflow the statically allocated array and end up in the place on the stack where "p" is stored, you will later try to free the random shit, hence the segfault)
a source to share