Массив внутри структуры, являющийся неправильным - PullRequest
3 голосов
/ 27 октября 2011

У меня есть следующий код:

#define MAX_NUMBER_OF_FRAMES 10

typedef struct my_frame_header {
    unsigned int ul_Src;
    unsigned int ul_Dest;
} MY_FRAME_HEADER;

typedef struct my_frame {
    MY_FRAME_HEADER x_FrameHeader;
    unsigned char  uc_Frame[3000];
} MY_FRAME;

int main(int argc, char *argv[])
{
    MY_FRAME *px_MyFrames;
    px_MyFrames = (MY_FRAME *)malloc(sizeof(MY_FRAME) * MAX_NUMBER_OF_FRAMES);

    // Use the x_MyFrames variable like an array
    px_MyFrames[0].uc_Frame[0] = 10;

    //free px_MyFrames
    free(px_MyFrames);

    return 1;
}

Будет ли вся память успешно освобождена? или мне нужно сделать указатель uc_Frame и память malloc в функции Init MY_FRAME? А затем в деструкторе освободить память для каждого uc_Frame px_MyFrames и затем освободить px_MyFrames? (Извините, если есть какие-либо ошибки компилятора, я просто написал на лету, чтобы дать вам основную идею). Если то, как я это изложил здесь, не является правильным и есть проблемы с памятью, не могли бы вы объяснить, что это могут быть за проблемы?.

Ответы [ 5 ]

4 голосов
/ 27 октября 2011

Поскольку uc_Frame - это массив, а не указатель, это прекрасно работает.Поскольку это массив, данные будут просто храниться непосредственно в структуре, которая в свою очередь будет иметь размер приблизительно 3008 байт.Таким образом, нет необходимости выделять какие-либо данные для uc_Frame, потому что снова это массив, а не просто указатель .

Было бы что-то вроде:

typedef struct my_frame {
    MY_FRAME_HEADER x_FrameHeader;
    unsigned int   ul_FrameSize;
    unsigned char *uc_Frame;
} MY_FRAME;

Тогда вам придется динамически выделять (и бесплатно, конечно) данные для uc_Frame, так как это всего лишь указатель, а не массив.И он не будет сохранен в структуре, которая, в свою очередь, будет иметь размер только около 16 или 24 байта.

1 голос
/ 27 октября 2011

Да, память будет освобождена путем вызова free.

Проверьте это:

#include <stdio.h>

typedef struct my_frame_header {
    unsigned int ul_Src;
    unsigned int ul_Dest;
} MY_FRAME_HEADER;

typedef struct my_frame {
    MY_FRAME_HEADER x_FrameHeader;
    unsigned char  uc_Frame[3000];
} MY_FRAME;

int main()
{
    printf("%d\n", sizeof(MY_FRAME));
}

При запуске печатается 3008.

Это означает, что когда вы вызываете malloc, он фактически выделяет 3008 байт пространства для каждого экземпляра MY_FRAME в px_MyFrames. Этого достаточно для хранения uc_Frame и x_FrameHeader. Следовательно, вам не нужно выделять uc_Frame самостоятельно. malloc помнит, что он выделил 3008 байт пространства, поэтому, когда вы его free, все освобождает.

1 голос
/ 27 октября 2011

Это будет успешно освобождено. Выделенное пространство памяти имеет размер sizeof(MY_FRAME), а sizeof(MY_FRAME) здесь содержит размер вашего массива и будет sizeof(MY_FRAME_HEADER) + sizeof(unsigned char) * 3000. Таким образом, при его освобождении диапазон памяти [px_MyFrames, px_MyFrames + sizeof(MY_FRAME)) будет освобожден.

Кроме того, еще один распространенный метод - хранить указатель массива в структуре следующим образом:

typedef struct my_frame {
    MY_FRAME_HEADER x_FrameHeader;
    unsigned char  *uc_Frame;
} MY_FRAME;

И на этот раз инициализация и финализация будут:

/* initialization */
px_MyFrames = (MY_FRAME *)malloc(sizeof(MY_FRAME) * MAX_NUMBER_OF_FRAMES);
/* and the following line matters */
px_MyFrames->uf_Frame = malloc(sizeof(ungisned char) * 3000);

/* when in finalization */
free(px_MyFrames->uf_Frame);
free(px_MyFrames);

Кстати, программа на С должна возвращать значение 0 при обычном возврате.

0 голосов
/ 27 октября 2011

Да, вся память будет освобождена.Регион, возвращаемый malloc, будет достаточно большим для хранения всего содержимого 10 struct my_frame с.Когда вы звоните free, он освобождает весь регион.

0 голосов
/ 27 октября 2011

Не волнует атрибут uc_Frame.Вы действительно правильно выделяете память для MAX_NUMBER_OF_FRAMES * sizeof(MY_FRAME), и вы используете и освобождаете ее нормально.

...