2009-05-13 6 views
0

Je suis en train d'utiliser un malloc court, quelque chose commeMalloc de 2 octets donne des problèmes

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 **** 

Je suis débogage pour quelques jours et désemparés,

Note (modifiée): Linux, et la version gcc 3.4.6 20060404


NUMÉRO UTILISATION Valgrind TROUVE

Mais, je voudrais documenter ici afin que mes collègues développeurs pourraient être au courant d'une telle situation ...

j'avais effectivement défini la structure

typedef union _SOME_STRUCT_ { 

    struct { 

    USHORT u:4; 
    USHORT v:4; 
    USHORT w:4; 

    } x; 

    USHORT word; 

} ALBUM, *PALBUM; 

et quelques-uns, où les autres dans le code que j'avais également défini

#define ALBUM "album" 

et, sizeof (ALBUM) faisait référence à la valeur #define plutôt que le typedef et par conséquent la question.

Ce qui me stupéfie est,

Est-ce permis en C?


+2

Quel OS/compilateur? – Arkadiy

+0

Il fonctionne parfaitement bien pour moi sur Windows XP/MinGW ... – DeadHead

+0

Linux, et gcc Version 3.4.6 20060404. – Alphaneo

Répondre

3

Essayez de passer votre programme par le biais valgrind, un programme open source et totalement gratuit, il pourrait peut-être vous aider à voir où est le problème. N'oubliez pas de compiler avec les symboles de débogage: gcc -g [etc].

Espérons que cette aide ..

+0

J'ai donné un coup de feu, et Valgrind a dit, "aucune fuite n'est possible." –

+0

Je n'ai pas utilisé Valgring depuis un moment, mais si votre programme tombe en panne pendant l'exécution, il doit au moins vous fournir un vidage de base. Votre programme s'est-il effondré? Et avez-vous un fichier core maintenant? Si oui, passez-le à gdb. Cela pourrait vous donner des informations plus vitales. –

0

Et si vous mettez gratuitement (p) dans votre if? Peut-être (peu probable) malloc échoue ...

+3

free (NULL) est valide (défini comme un no-op), et ne devrait pas entraîner un plantage. – Michael

+0

delete NULL est valide, je ne suis pas sûr de libre (NULL) – Arkadiy

+0

http://www.opengroup.org/onlinepubs/009695399/functions/free.html "Si ptr est un pointeur nul, aucune action ne doit se produire." –

2

Peut-être un problème d'alignement. Est-il encore plantage si vous faites quelque chose comme ceci:

struct { 
    USHORT u:4; 
    USHORT v:4; 
    USHORT w:4; 
    USHORT :4; 
    } x; 
+0

oui, il plante ... – Alphaneo

+1

En dehors d'un bug de code-gen, le compilateur devrait générer des structures de données correctement alignées pour ce code. Le reste: 4 est inutile puisque le mot USHORT dans l'union force la structure à 2 octets. – Michael

3

Cette version du code fonctionne pour moi.

#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 **** 
} 

C'est debug GDB d'un Cygwin sous Windows XP. Ignorez les valeurs dans $ 4, les données ne sont pas initialisées.

(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} 

Le programme s'est arrêté normalement.

Avez-vous quelque chose d'autre dans le code en plus de ces lignes?

Édition: et, libre (0); est une opération valide.

+0

En effet - Y at-il quelque chose de malloc'ed à côté de struct? – Arkadiy

2

Le problème n'est pas avec le code mais quelque chose qui se passe avant ou dans un autre thread.

Je réduirais les sections du programme jusqu'à ce qu'il arrête de se bloquer, puis je le rajouterais pas à pas jusqu'à ce que vous compreniez quelle section est à l'origine de cela.Selon le système d'exploitation/la plate-forme, vous pouvez également essayer des outils de vérification de la mémoire, valgrind/_crtdebug etc.

1

Si ce problème survient, vous pouvez démarrer votre session de débogage avec un appel à memcheck.

Une cause de plantage de la mémoire est le plus souvent le tas ou la libération deux fois du même pointeur.

1

Vous appelez inconditionnellement free() sans vérifier si le malloc a réussi, donc si le malloc a échoué et que p est un pointeur NULL, alors vous appelez free (NULL).

Déplacez le libre à l'intérieur du bloc if (p).

Ceci n'est peut-être pas la cause des plantages, et ne devrait pas l'être si la mémoire n'est pas limitée, mais c'est néanmoins un bug.

Ajouté plus tard: doh, free (NULL) est explicitement autorisé, par http://www.opengroup.org/onlinepubs/009695399/functions/free.html - désolé.

1

Si vous faites des choses entre le malloc et libre, vous pourriez être un tableau différent ROUE LIBRE par hasard et corrompt votre propre pile

(si « p » ne se produit pas dans un registre, et vous débordez un tableau alloué statiquement et frappez l'endroit sur la pile où 'p' est stocké, vous essaierez plus tard de libérer la merde au hasard, d'où le segfault)

Questions connexes