Malloc 2 байтов дает проблемы - PullRequest
0 голосов
/ 13 мая 2009

Я пытаюсь использовать malloc short, что-то вроде

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

Я отлаживаю пару дней и ничего не понимаю,

Примечание (отредактировано): Linux и gcc Версия 3.4.6 20060404


ВЫПУСК НАЙДЕНО С ИСПОЛЬЗОВАНИЕМ VALGRIND

Но тогда я хотел бы документировать это здесь, чтобы мои коллеги-разработчики могли знать о такой ситуации ...

Я на самом деле определил структуру как

typedef union _SOME_STRUCT_ {

   struct {

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

   } x;

   USHORT word;

} ALBUM, *PALBUM;

и кое-где еще в коде, который я также определил

#define ALBUM "album"

Итак, sizeof (ALBUM) ссылался на значение #define, а не на typedef и, следовательно, на проблему.

Меня поражает то, что

Разрешено ли это в C?


Ответы [ 8 ]

3 голосов
/ 13 мая 2009

Эта версия кода работает для меня.

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

Это отладка GDB от Cygwin в 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}

Игнорировать значения в $ 4, данные неинициализированы. Программа завершилась нормально.

У вас есть что-то еще в коде, кроме этих строк?

Редактировать: и, бесплатно (0); является допустимой операцией.

3 голосов
/ 13 мая 2009

Попробуйте передать вашу программу через valgrind , программу с открытым исходным кодом и полностью бесплатную, возможно, она поможет вам понять, в чем проблема. Не забудьте скомпилировать с символами отладки: gcc -g [etc].

Надеюсь, что это поможет ..

2 голосов
/ 13 мая 2009

Проблема не в коде, а в том, что происходит раньше или в другом потоке.

Я бы уменьшал разделы программы до тех пор, пока она не перестанет падать, а затем добавил ее шаг за шагом, пока вы не выясните, какой раздел вызывает это. В зависимости от ОС / платформы вы также можете попробовать некоторые инструменты проверки памяти, valgrind / _crtdebug и т. Д.

2 голосов
/ 13 мая 2009

Может быть проблема с выравниванием. По-прежнему происходит сбой, если вы делаете что-то вроде этого:

   struct {
     USHORT u:4;
     USHORT v:4;
     USHORT w:4;
     USHORT  :4;
   } x;
1 голос
/ 13 мая 2009

Если вы делаете вещи между malloc и free, вы можете случайно переполнить другой массив и испортить свой собственный стек

(если «p» не находится в регистре, и вы заполнили статически распределенный массив и попали в место в стеке, где хранится «p»), вы позже попытаетесь освободить случайное дерьмо отсюда и ошибка)

1 голос
/ 13 мая 2009

Вы безоговорочно вызываете free (), не проверяя, удалось ли malloc успешно, поэтому, если malloc завершился неудачно, а p является указателем NULL, вы вызываете free (NULL).

Перемещение свободного внутри блока if (p).

Это может быть не причиной сбоев, и не должно быть, если не ограничено памятью, но, тем не менее, является ошибкой.

Добавлено позже: doh, free (NULL) явно разрешено, за http://www.opengroup.org/onlinepubs/009695399/functions/free.html - извините.

1 голос
/ 13 мая 2009

Если эта проблема возникает, когда вы можете ее отладить, вы можете начать сеанс отладки с вызова memcheck.

Причиной сбоя памяти чаще всего является куча или освобождение одного и того же указателя дважды.

0 голосов
/ 13 мая 2009

Что если вы положите free (p) в свой if? Возможно (маловероятно), что malloc не работает ...

...