3

I have the following code:

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

Will all the memory be succesfully freed? or do I need to make uc_Frame a pointer and malloc memory in an Init function of MY_FRAME? And then in the destructor free the memory for each uc_Frame of px_MyFrames and then free px_MyFrames? (Sorry if there are any compiler errors, I just wrote on the fly to give you the basic idea). If the way I put it here is not the right one and there are memory problems could you explain what those problems might be?.

1
  • Welcome to StackOverflow, I hope you read the FAQ. Commented Oct 27, 2011 at 12:58

5 Answers 5

4

Since uc_Frame is an array and not a pointer, this perfectly works. As it's an array, the data will just be stored directly in the struct, which in turn will have a size of approximately 3008 bytes. So there is no need to malloc any data for uc_Frame, because again it's an array and not just a pointer.

Would it have been something like:

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

Then you would have to allocate (and free, of course) the data for uc_Frame dynamically, as it's just a pointer and not an array. And it would not be stored in the struct, which in turn would have a size of only about 16 or 24 byte.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I just wasn't sure about the Array being handled correctly or not. But as you and the others have mentioned it works perfectly good without the need of a pointer and another malloc/free.
@J.C. In case this (or any other) answer was the correct answer to your question, accepting and up-voting is the correct response. If you don't know what I'm talking about and how this Q&A site works, take a look into the FAQ.
1

Yes, the memory will be freed by calling free.

Check this out:

#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));
}

When run, it prints 3008.

That means when you call malloc, it's actually allocating 3008 bytes of space for each instance of MY_FRAME in px_MyFrames. This is enough space to hold uc_Frame and x_FrameHeader. Therefore, you don't need to allocate uc_Frame yourself. malloc remembers that it has allocated 3008 bytes of space so that when you free it, everything gets deallocated.

Comments

1

It would be successfully freed. The memory space you allocated has a size of sizeof(MY_FRAME), and sizeof(MY_FRAME) here contains the size of your array and it would be sizeof(MY_FRAME_HEADER) + sizeof(unsigned char) * 3000. So when freeing it, the memory range [px_MyFrames, px_MyFrames + sizeof(MY_FRAME)) would be freed.

Also, another common method is to hold a pointer of an array in the struct like this:

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

And this time the initialization and finalization would be:

/* 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);

By the way, a C program shall give a return value of 0 on its normal returning.

5 Comments

Yeah sorry it was just a fast written example, but you're right, it should return 0.
yeah that's what I meant with the 2nd option only that I would need a for loop to malloc memory for every uc_Frame, not just the first like yours, if I were to use all of the MAX_NUMBER_OF_FRAMES. And the same for freeing every uc_Frame.
@J.C. Personally I don't prefer either form of the declaration of struct, though both are okay. It depends on the specific data to store and the usage.
@Pangyu CHEN How would you declare them? I have a frame (Ethernet, Fibre Channel, etc) which has a Header part with some information about the destination, source, length, protocol, etc. Then I have the actual payload data, which could be anything up to 3000 bytes. As I see it is the most simple form I can have but if there is a better way I'd like to know to learn it for future projects.
@J.C. It'll look just the same as what I wrote in the answer above, in which the struct holds a pointer to a dynamically allocated memory region. I'm using this style to implement resize-able arrays to simulate std::vector<> in c++ in some project.
0

Don't care about uc_Frame attribute. You are really allocating memory for MAX_NUMBER_OF_FRAMES * sizeof(MY_FRAME) correctly and you are using and freeing it ok.

Comments

0

Yes, all of the memory will be freed. The region returned by malloc will be big enough to store the entire contents of 10 struct my_frames. When you call free it will release the entire region.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.