views:

327

answers:

8

I am trying to use a malloc of short, 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 am debugging for a couple of days and clueless,

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 might be aware of such a situation ...

I had 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 some-where else in the code I had also defined

#define ALBUM "album"

And so, sizeof (ALBUM) was referring to the #define value rather than the typedef and hence the issue.

The thing that amazes me is,

Is this allowed in C?


A: 

What if you put free(p) in your if? Maybe (unlikely) malloc is failing...

paquetp
free(NULL) is valid (defined as a no-op), and should not result in a crash.
Michael
delete NULL is valid, I am not sure about free(NULL)
Arkadiy
http://www.opengroup.org/onlinepubs/009695399/functions/free.html "If ptr is a null pointer, no action shall occur."
Chris Lutz
+2  A: 

Might be an alignment issue. Does it still crash if you do something like this:

   struct {
     USHORT u:4;
     USHORT v:4;
     USHORT w:4;
     USHORT  :4;
   } x;
sybreon
yes, it's crashing ...
Alphaneo
Outside of a code-gen bug, the compiler should be generating properly aligned data structures for this code. The remaining : 4 is unnecessary since the USHORT word in the union forces the struct to be 2 bytes.
Michael
+3  A: 

Try to pass your program through valgrind , an open source program and totaly free, maybe it could help you to see where is the issue. Don't forget to compile with debug symbols: gcc -g [etc] .

Hope this help..

yves Baumes
I gave this a shot, and valgrind said, "no leaks are possible."
Matthew Flaschen
I didn't use Valgring for a while, but if your program crash while valgring execute it, it must at least provide you a core dump. Did your program crashed down ? And do you have a core file now ? If so , pass it to gdb. It could give you more vital information.
yves Baumes
+3  A: 

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 debug from a 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 the values in $4, data is uninitialized. Program exited normally.

Do you have something else in the code besides these lines?

Edit: and, free(0); is a valid operation.

nik
Indeed - is there anything malloc'ed next to struct?
Arkadiy
+2  A: 

The problem is not with the code but something that is happening before or in another thread.

I would reduce sections of the program until it stops crashing and then add it back in step by step until you figure out what section is causing this. Depending on the OS/Platform you could also try some memory checking tools, valgrind/_crtdebug etc..

Jon Clegg
+1  A: 

If this issue is happening where you could debug it you could start your debug session with a call to memcheck.

A cause for a crash for memory is most often heap or freeing the same pointer twice.

AndrewB
+1  A: 

You're unconditionally calling free() without checking if the malloc succeeded, so if the malloc failed and p is a NULL pointer, then you're calling free(NULL).

Move the free inside the if (p) block.

This might not be the cause of the crashes, and shouldn't be if not memory-constrained, but is a bug nonetheless.

Added later: doh, free(NULL) is explicitly allowed, per http://www.opengroup.org/onlinepubs/009695399/functions/free.html -- sorry.

Phil P
+1  A: 

If you're doing stuff in between the malloc and free, you could be overrunning a different array by accident and corrupting your own stack

(if 'p' doesn't happen to be in a register, and you overrun a statically-allocated array and hit the place on the stack where 'p' is stored, you will then later attempt to free random crap, hence the segfault)

Paul Betts