My favorite:

#include <stdlib.h>

struct st *x = malloc(sizeof *x); 

Note that:

  • x must be a pointer
  • no cast is required
  • include appropriate header
Answer from dirkgently on Stack Overflow
๐ŸŒ
Learn C
learn-c.org โ€บ en โ€บ Dynamic_allocation
Dynamic allocation - Learn C - Free Interactive C Tutorial
This tells the compiler that we ... a pointer of type person to the newly allocated data. The memory allocation function malloc() reserves the specified memory space....
Discussions

memory management - malloc for struct and pointer in C - Stack Overflow
Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... Now, suppose I want to define a vector y and allocate memory for it. struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector)); More on stackoverflow.com
๐ŸŒ stackoverflow.com
pointers - How do I define a struct and properly allocate memory for it in C? - Stack Overflow
For the constructor I'm using a different function which recieves a string as input which is encoded into a decimal code. Also this function recieves another input which is a pointer to an int array (the pointer defined in the struct) and the problem is I'm using the malloc() function to allocate memory ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
C struct and memory allocation - Stack Overflow
Bring the best of human thought ... Stack Internal ... When you allocate space for memory how do you tell if you need to allocate more space for it? Is there a check or so you can do on your new memory to make sure it is doing OK? ( allocated memory for a struct)... More on stackoverflow.com
๐ŸŒ stackoverflow.com
How to correctly allocate memory for an array of structs in C? - Stack Overflow
This is the first time I'm using structs as I am still relatively new to C. When I try to input values for 3 structs the program crashes, but it works fine for 1 and 2. I think I may not actually be More on stackoverflow.com
๐ŸŒ stackoverflow.com
March 8, 2015
๐ŸŒ
Reddit
reddit.com โ€บ r/c_programming โ€บ best practice on allocating memory for a struct that has dynamic array members
r/C_Programming on Reddit: Best practice on allocating memory for a struct that has dynamic array members
February 29, 2024 -

Hi all! I am very new to C but am familiar with Python & Go quite a bit. Memory allocation is a new concept to me, but I want to start with best practices.

Lets say I want to create a struct that has some members, where one of them happens to be a pointer which I will size dynamically as an array.

Here is what I am doing in my init_my_struct(int n) function. I want to understand if I am doing something that is bad practice here

#include <stdlib.h>
#include <stdio.h>

struct my_struct {
        int n;
        int *my_arr; // this will be dynamically grown based on user arg
};

struct my_struct * init_my_struct(int n)
{
        // allocate memory for one struct
        struct my_struct *ms = malloc(sizeof(struct my_struct));
        
        // use -> syntax since ms is a pointer
        ms->n = n;
        ms->my_arr = malloc(sizeof(int)*n);
        return ms;
}

int main(int argc, char *argv[])
{
        if (argc < 2) return 1;

        int n = atoi(argv[1]);
        
        // initialize the struct members
        struct my_struct *ms = init_my_struct(n);
        
        // check out contents of my struct
        printf("my struct's n: %d\n", ms->n);
        printf("my struct's my_arr: \n");
        for (int i = 0; i < n; i++) {
                printf("%d\n", ms->my_arr[i]);
        }
        free(ms); // clean up the memory

        return 0;
}

Any pointers or tips would be great! Thank you!

๐ŸŒ
W3Schools
w3schools.com โ€บ c โ€บ c_memory_struct.php
C Structures and Dynamic Memory
This is useful when you don't know how many structs you'll need in advance, or want to save memory by only allocating what's necessary (e.g., in a car dealership program where the number of cars is not fixed). You can use the malloc() function to ...
Top answer
1 of 8
198

No, you're not allocating memory for y->x twice.

Instead, you're allocating memory for the structure (which includes a pointer) plus something for that pointer to point to.

Think of it this way:

         1          2
        +-----+    +------+
y------>|  x------>|  *x  |
        |  n  |    +------+
        +-----+

You actually need the two allocations (1 and 2) to store everything you need.

Additionally, your type should be struct Vector *y since it's a pointer, and you should never cast the return value from malloc in C.

It can hide certain problems you don't want hidden, and C is perfectly capable of implicitly converting the void* return value to any other pointer.

And, of course, you probably want to encapsulate the creation of these vectors to make management of them easier, such as with having the following in a header file vector.h:

#include <stddef.h>

struct Vector {
    double *data;    // Use readable names rather than x/n.
    size_t size;
};

struct Vector *newVector(size_t sz);
void delVector(struct Vector *vector);
//void setVectorItem(struct Vector *vector, size_t idx, double val);
//double getVectorItem(struct Vector *vector, size_t idx);

Then, in vector.c, you have the actual functions for managing the vectors:

#include <stdlib.h>
#include "vector.h"

// Atomically allocate a two-layer object. Either both layers
// are allocated or neither is, simplifying memory checking.

struct Vector *newVector(size_t sz) {
    // First, the vector layer.

    struct Vector *vector = malloc(sizeof (struct Vector));
    if (vector == NULL)
        return NULL;

    // Then data layer, freeing vector layer if fail.

    vector->data = malloc(sz * sizeof (double));
    if (vector->data == NULL) {
        free(vector);
        return NULL;
    }

    // Here, both layers worked. Set size and return.

    vector->size = sz;
    return vector;
}

void delVector(struct Vector *vector) {
    // Can safely assume vector is NULL or fully built.

    if (vector != NULL) {
        free(vector->data);
        free(vector);
    }
}

By encapsulating the vector management like that, you ensure that vectors are either fully built or not built at all - there's no chance of them being half-built.

It also allows you to totally change the underlying data structures in future without affecting clients. For example:

  • if you wanted to make them sparse arrays to trade off space for speed.
  • if you wanted the data saved to persistent storage whenever changed.
  • if you wished to ensure all vector elements were initialised to zero.
  • if you wanted to separate the vector size from the vector capacity for efficiency(1).

You could also add more functionality such as safely setting or getting vector values (see commented code in the header), as the need arises.

For example, you could (as one option) silently ignore setting values outside the valid range and return zero if getting those values. Or you could raise an error of some description, or attempt to automatically expand the vector under the covers(1).


In terms of using the vectors, a simple example is something like the following (very basic) main.c

#include "vector.h"

int main(void) {
    struct Vector *myvec = newVector(42);
    myvec->data[0] = 2.718281828459;
    delVector(myvec);
}

(1) That potential for an expandable vector bears further explanation.

Many vector implementations separate capacity from size. The former is how many elements you can use before a re-allocation is needed, the latter is the actual vector size (always <= the capacity).

When expanding, you want to generally expand in such a way that you're not doing it a lot, since it can be an expensive operation. For example, you could add 5% more than was strictly necessary so that, in a loop continuously adding one element, it doesn't have to re-allocate for every single item.

2 of 8
5

The first time around, you allocate memory for Vector, which means the variables x,n.

However x doesn't yet point to anything useful.

So that is why second allocation is needed as well.

๐ŸŒ
Quora
quora.com โ€บ When-I-declare-a-struct-in-C-does-it-automatically-allocate-memory-for-me-using-malloc
When I declare a struct in C, does it automatically allocate memory for me using malloc()? - Quora
Answer (1 of 13): First, a general principle: no matter what you do, [code ]malloc()[/code] is never invoked automagically. When you declare a [code ]struct[/code], you declare a type. A type, by itself, consumes no memory at runtime. When you declare a variable of the struct type, memory is al...
๐ŸŒ
Delft Stack
delftstack.com โ€บ home โ€บ howto โ€บ c malloc struct
How to Allocate Struct Memory With malloc in C | Delft Stack
February 12, 2024 - Itโ€™s a basic example showcasing how to dynamically allocate memory for a struct, access its members, perform operations, and release the allocated memory to prevent memory leaks. Itโ€™s often useful to declare an array of structures, which may require a larger memory region than available on the stack. Thus, we need to allocate the array as dynamic memory. In this method, memory is allocated to store an array of structures using malloc. The following example code demonstrates the case when the array of 100 pointers to the MyObject structs is declared on the stack, but each individual MyObject object is allocated on dynamic memory (heap).
Find elsewhere
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 67994197 โ€บ how-do-i-define-a-struct-and-properly-allocate-memory-for-it-in-c
pointers - How do I define a struct and properly allocate memory for it in C? - Stack Overflow
It's unclear whether you're expected to manage the memory of the array inside, but this is functionally the setup you need for allocating the containing structure.
๐ŸŒ
Avabodh
avabodh.com โ€บ cin โ€บ structure.html
Memory Allocation for Structure | avabodh.com
If we create an object of some structure, then the compiler allocates contiguous memory for the data members of the structure. The size of allocated memory is at least the sum of sizes of all data members. The compiler can use padding and in that case there will be unused space created between ...
๐ŸŒ
Programiz
programiz.com โ€บ c-programming โ€บ examples โ€บ structure-dynamic-memory-allocation
C Program to Store Data in Structures Dynamically
#include <stdio.h> #include <stdlib.h> ... "); scanf("%d", &noOfRecords); // Memory allocation for noOfRecords structures ptr = (struct course *)malloc(noOfRecords * sizeof(struct course)); for (int i = 0; i < noOfRecords; ++i) { printf("Enter subject and marks:\n"); scanf("%s ...
๐ŸŒ
Cprogramming
cboard.cprogramming.com โ€บ c-programming โ€บ 66209-struct-pointer-memory-allocation.html
Struct/pointer/memory allocation
As someone has already mentioned, you need to pass a pointer to a pointer to the structure in your malloc_mystruct() functions argument to accomplish what you want to do. Here's how it can be done: ... Last edited by xeddiex; 06-03-2005 at 12:03 PM. ... Thanks for the replies and the help!
Top answer
1 of 1
8

If you're just using a simple struct, you don't need more memory allocated for it as time goes on. You just create the struct, use it, and clean it up if required. If you are dynamically allocating your struct (ie: with malloc), then you test the value of the pointer-to-struct you create and see if it is NULL. If it is NULL, then the memory allocation failed, and you can either retry, or abandon further operations (ie: exit on error condition).

#include <stdio.h>

typedef struct myStruct {
  int i;
  char c;
} myStruct;

int main(void) {
  // Static allocation, no cleanup required
  myStruct staticStruct;
  staticStruct.i = 0;
  staticStruct.c = 'c';

  // Dynamic allocation, requires cleanup
  myStruct* dynamicStruct;
  dynamicStruct = malloc(sizeof(myStruct));
  if (dynamicStruct == NULL) {
    printf("Memory allocation error!\n");
    return (-1);
  } else {
    printf("Successfully allocated memory!\n");
  }

  dynamicStruct->i = 1;
  dynamicStruct->c = 'd';
  free(dynamicStruct);  // Release allocated memory
  dynamicStruct = NULL; // Somewhat common practise, though not 100% necessary
  return 0;
}

Now, if you need to create an array of dynamically allocated structs, and you've used them all up, and need more, you'd likely be best off with a slightly more complicated approach, like a dynamically allocated linked list of structs. A good example can be found in the "References" section below. Also, I've included a link to a somewhat related question I answered on memory allocation in C. It has some good examples that might also help clear up this topic for you.

References


  1. C Linked List Data Structure Explained with an Example C Program, Accessed 2014-03-25, <http://www.thegeekstuff.com/2012/08/c-linked-list-example/>
  2. Difference between declared string and allocated string, Accessed 2014-03-25, <https://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string>
๐ŸŒ
Fresh2Refresh
fresh2refresh.com โ€บ home โ€บ c programming tutorial โ€บ c โ€“ struct memory allocation
Memory allocation in C
September 22, 2020 - There are 5 members declared for structure in above program. In 32 bit compiler, 4 bytes of memory is occupied by int datatype. 1 byte of memory is occupied by char datatype and 4 bytes of memory is occupied by float datatype. Please refer below table to know from where to where memory is allocated for each datatype in contiguous (adjacent) location in memory.
๐ŸŒ
Dartmouth College
cs.dartmouth.edu โ€บ ~campbell โ€บ cs50 โ€บ dynamicmem.html
Pointers and Dynamic Memory Allocation
The dynamic memory management functions are supported by the standard C library and their detailed function protypes are found in stdlib.h. Memor allocation functions allow programmers to dynamically allocate memory from the heap for variables, arrays, and structures; rather that statically ...
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ explain-the-dynamic-memory-allocation-of-pointer-to-structure-in-c-language
Explain the dynamic memory allocation of pointer to structure in C language
#include <stdio.h> #include <stdlib.h> ... of persons: "); scanf("%d", &n); // allocating memory for n numbers of struct person ptr = (struct person*) malloc(n * sizeof(struct person)); for(i = 0; i < n; ++i){ printf("Enter name and age respectively: "); // To access members of ...
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 33191801 โ€บ how-to-allocate-memory-of-a-struct
c - How to allocate memory of a struct? - Stack Overflow
typedef unsigned char uchar; typedef struct { uchar Seq; uchar Ack; uchar Flags; } Header; #define FRAME_PAYLOAD_SIZE 50 struct Frame_t { Header header; char data[FRAME_PAYLOAD_SIZE]; uchar CRC; }; typedef struct Frame_t Frame; struct Sender { uchar winSize; struct sendSlot { struct timeval timeout; Frame msg; } sendQ[5]; }; initSend(Sender* sender) { sender->winSize = -1; char* send_buf = (char*) malloc(5 * sizeof(sender->sendQ[0])); memset(send_buf, 0, 5 * sizeof(sender->sendQ[0])); int i; for (i=0; i<sizeof(sender->sendQ)/sizeof(sender->sendQ[0]); i++) { memset(sender->sendQ[i].timeout, 0, sizeof(struct timeval)); sender->sendQ = NULL; } } ... Are you trying to define a function inside main()? If so, stop right there. ... Just use calloc instead of malloc, and you'll start with zeroed-out memory.
Top answer
1 of 3
43

Short answer: they are allocated with the order as they declared in the struct.


Example:

#include <stdio.h>
#include <string.h>

struct student 
{
    int id1;
    int id2;
    char a;
    char b;
    float percentage;
};

int main() 
{
    int i;
    struct student record1 = {1, 2, 'A', 'B', 90.5};

    printf("size of structure in bytes : %d\n", 
        sizeof(record1));

    printf("\nAddress of id1        = %u", &record1.id1 );
    printf("\nAddress of id2        = %u", &record1.id2 );
    printf("\nAddress of a          = %u", &record1.a );
    printf("\nAddress of b          = %u", &record1.b );
    printf("\nAddress of percentage = %u",&record1.percentage);

    return 0;
}

Output:

size of structure in bytes : 16 
Address of id1 = 675376768
Address of id2 = 675376772
Address of a = 675376776
Address of b = 675376777
Address of percentage = 675376780

The pictorial representation of above structure memory allocation is given below. This diagram will help you to understand the memory allocation concept in C very easily.


Further reading: check out here (also the source for the above example) for C โ€“ Structure Padding and Structure dynamic memory allocation in C.

2 of 3
7

You are guaranteed that field3 comes after field2, which comes after field1, and that field1 is at the start of the memory (i.e. there's no padding before field1). However, they may be padding in between the other members (and even after field3). In short, the order in which they are declared is the order in which they are laid out in memory, though exact alignment and padding is implementation defined (but there won't be any padding before the first member).