Variables can be created on the stack, on the heap, or in static memory, regardless of their type. The reason the program you posted uses malloc() is because it is demonstrating dynamically allocating elements for a linked list. Answer from Updatebjarni on reddit.com
🌐
Reddit
reddit.com › r/learnprogramming › why do structs need to be created on the heap in c or generally ?
r/learnprogramming on Reddit: Why do structs need to be created on the heap in C or generally ?
January 10, 2022 -

Why is it so important to create space with malloc for structs so the struct will be on the heap. Why cant the struct be created without malloc and stay on the stack ? We are being thought this concept in school, but i dont understand why.

// A simple C program for traversal of a linked list
#include <stdio.h>
#include <stdlib.h>

struct Node {
	int data;
	struct Node* next;
};

// This function prints contents of linked list starting from
// the given node
void printList(struct Node* n)
{
	while (n != NULL) {
		printf(" %d ", n->data);
		n = n->next;
	}
}

int main()
{
	struct Node* head = NULL;
	struct Node* second = NULL;
	struct Node* third = NULL;

	// allocate 3 nodes in the heap
	head = (struct Node*)malloc(sizeof(struct Node));
	second = (struct Node*)malloc(sizeof(struct Node));
	third = (struct Node*)malloc(sizeof(struct Node));

	head->data = 1; // assign data in first node
	head->next = second; // Link first node with second

	second->data = 2; // assign data to second node
	second->next = third;

	third->data = 3; // assign data to third node
	third->next = NULL;

	printList(head);

	return 0;
}
🌐
Reddit
reddit.com › r/c_programming › is it better to allocate a structs on the stack or on the heap?
r/C_Programming on Reddit: Is it better to allocate a structs on the stack or on the heap?
July 29, 2022 -

I just defined a new struct type typedef struct graph_struct {} struct; and I need to make one of them in my main function. There are two options for a constructor:

  1. Declare a graph in main(), and pass its address to the constructor. Return nothing.

  2. Pass nothing to the constructor, malloc a graph inside of it, and return a pointer to the graph.

I prefer 2), but I think that memory on the heap is slower to work with than memory on the stack. And my program does need to be really fast.

Is there any reason to prefer one over the other?

🌐
Reddit
reddit.com › r/c_programming › why are structs frequently heap allocated unnecessarily?
Why are structs frequently heap allocated unnecessarily? : r/C_Programming
March 23, 2021 - So sometimes you might know the size at compile time and still allocate on the heap; stack space is limited ... If it’s not possible to statically init via ={…}, mallocating inside the API can eliminate the allocated-but-uninitialized case—or rather, reduce it to a single non-/null pointer. It also allows you to use a struct ending in a flex/zero-length array (flex: C99; ZLA: MS ext’n optionally supported in GNU-dialect compilers), or use a struct involving a VLA (mostly GCC, GNU99) more safely.
Top answer
1 of 3
12

In this function,

void
allocateMem(struct myStruct *struct1)
{
    struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
}

struct1 is passed by value. Any changes you make to it in the function are not visible from the calling function.

A better alternative:

struct myStruct* allocateMem()
{
    struct myStruct *struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
    return struct1;
}

Change the calling function to:

int
main(int argc, char *argv[])
{
    struct myStruct *struct1 = allocateMem();
    printf("number: %d\n", struct1->number);

    // Make sure to free the memory.
    free(struct1);

    return 0;
}
2 of 3
5

A pointer is just an integer in reality, when you pass in struct1 to your function since struct1 is null you are just passing in a 0 to your function in reality. that value gets passed on the stack and you do a heap allocation and update the stack value with the new address. but when you return from the function, that value just gets popped of the stack and you have leaked that memory. the value of struct1 in main (which is also on the stack still keeps its value 0(NULL). so you have to pass in a pointer to your pointer if you want to update that value, or what might be easier is just to return the malloc'd pointer from your function.

This is one way you could modify your function to work:

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

struct myStruct
{
    int number;
};

struct myStruct*
allocateMem()
{
    struct myStruct* struct1 = malloc(sizeof(struct myStruct));
    struct1->number = 500;
    printf("struct1->number: %d\n", struct1->number);
    return struct1;
}

int
main(int argc, char *argv[])
{
    struct myStruct *struct1 = allocateMem();
    printf("number: %d\n", struct1->number);
    return 0;
}
🌐
Reddit
reddit.com › r/c_programming › memory allocation for char array inside struct
r/C_Programming on Reddit: Memory allocation for char array inside struct
July 28, 2018 -

Hey friends,

I'm sure somebody on the internet jas alread answered this, but I honestly haven't found a suitable answer for me.

Let's say we have a struct like this:

typedef struct {
    char *name;
    int age;
} Human;

And a kind of "constructor" function like this:

Human *human_new(char *name, int age)
{
    Human *this = (Human *) malloc(sizeof(Human));

    this->name = name;
    this->age  = age;

    return this;
}

My question is, do I need to allocate memory for the char pointer name of the struct or is the assignment of this->name enough?

Top answer
1 of 5
25
My question is, do I need to allocate memory for the char pointer name of the struct or is the assignment of this->name enough? Depends on what you want to do. If you simply assign to this->name, then the object you've just allocated won't "own" the pointer or the contents of the string to which it points. It has merely borrowed the pointer. The string contents could change at any time, or the pointer could be invalidated by being freed, without the Human object even knowing. Borrowing pointers can indeed be useful in some cases, but it's almost certainly not what you want here. You probably want to strdup the name argument to create a completely new string with the same contents. You might even want to change name to be a const char *, to emphasise the fact that the value being passed is going to be copied, not borrowed. If you do create a whole new string for that name field, you will probably want to provide a destructor for your Human objects, e.g.: void human_free(Human *this) { free(this->name); free(this); } Also, on a completely different note, the cast in: Human *this = (Human *) malloc(sizeof(Human)); isn't necessary in C. Object pointers can be converted to and from void pointers without casts.
2 of 5
5
Yes, you will need to allocate memory for whatever you want to put in the name of the struct. malloc(sizeof(Human)) will allocate enough space for a char pointer and an int, it won't allocate memory for the contents of name because it has no idea what the size will be. If you know the upper bound on the size of name, or are happy to enforce one, you could change the definition of the struct to: typedef struct { char name[100]; int age; } Human; Then when you call malloc(sizeof(Human)) you'll get enough space for a 'string' containing up to 100 characters (only 99 usable because of the null terminator) and an int. If you do that, it would probably be sensible to define the maximum length of a name as #define MAX_HUMAN_NAME_LENGTH 100 to be clearer and so you only have to change it in one place.
🌐
Reddit
reddit.com › r/c_programming › how are structure items treated? stack or heap?
How are structure items treated? stack or heap? : r/C_Programming
March 14, 2025 - When desc is an array, it is part of the struct which is created on the heap by malloc. Perhaps the UB you encountered was related to not leaving space for the terminating \0? typedef struct SFoo { short x; char y[30]; } Foo; int main() { Foo* newFoo = (Foo*)malloc(sizeof(Foo)); newFoo->x = 123; strncpy(newFoo->y, "thingthingthingthingthingthingthing", 29); printf("%d\n", sizeof(Foo)); puts(newFoo->y); return 0; } // Output is: // 32 // thingthingthingthingthingthin ... It is not enough to allocate place for the terminating null char.
🌐
Quora
quora.com › How-do-you-allocate-memory-for-a-struct-on-the-heap-in-C-Whats-the-difference-between-allocating-space-with-new-and-malloc
How to allocate memory for a struct on the heap in C++? What's the difference between allocating space with new and malloc - Quora
Answer (1 of 3): If you can use operator new instead of malloc, do it. malloc and free are for C code compatibility, and while not deprecated, they do not have the internal code to understand objects. malloc is a byte-oriented C function that returns raw bytes of contiguous uninitialized memory,...
🌐
Reddit
reddit.com › r/c_programming › correct way to allocate memory for struct with variable struct array?
r/C_Programming on Reddit: Correct way to allocate memory for struct with variable struct array?
February 22, 2022 -

Hi,

currently I'm train my C skills (or get some in general, lol) and make a little training project: classical tic tac toe. I will "overcomplicate" the project on purpose with the intention to use many language skills as possible.

I will represent the "board" with this two structures:

struct game_board_bitmap {
    char player: 2;
};

struct game_board {
    unsigned int width;
    unsigned int height;
    unsigned int size;
    struct game_board_bitmap* fields[];
};

A classic board has a width and height of 3, so a size of 9. Every field should be represented with the struct game_board_bitmap and saved in a variable array in the struct game_board.

The purpose of the shown structure is to train the correct handling of malloc, free etc.

And this is also where I reach my limits. How do I create this nested structure correctly? I have tried it via the following way:

struct game_board* tictactoe_init_game_board(unsigned int const width, unsigned int const height) {
    struct game_board* board = malloc(sizeof(struct game_board) + (width * height) * sizeof(struct game_board_bitmap));

    // malloc test removed for space savings

    board->width = width;
    board->height = height;
    board->size = width * height;

    for (int i = 0; i < board->size; i++) {
        board->fields[i]->player = 0; // 0 is default, field not assigned to any player
    }

    return board;
}

If I want access the board via printf("%c", board->fields[2]->player); the program crashes with a SIGSEGV. So I think I have done something wrong.

Can someone please explain to me what exactly I am doing wrong or how to do it right? Thank you! :)

Find elsewhere
🌐
Reddit
reddit.com › r/c_programming › best practice for struct management
r/C_Programming on Reddit: Best practice for struct management
February 29, 2024 -

EDIT: Added clarifications

I was wondering what the best practice for struct management is? I assume it will depend on the situation, but I have been doing it 2 different ways and was wondering if there are more, and if any is better than the other.

Assuming I have a struct person and a list of people struct person_list, I used to always allocate each struct with malloc, and keep track of the pointer in the list. But recently I have been experimenting with having the list keep an array of struct person (which can be dynamically increased with realloc) and copying structs into the array either using memcpy or dereference. When an person struct is needed, I return the pointer from the list. The list itself is usually malloced, so technically the structs are still on the heap.

The main reason for the last approach is the reduced memory management of each struct, and the fact I could create struct with designated initialisers.

/* list_add_person will copy the person struct, so stack allocated is fine. */
list_add_person(&list, &(struct person){
    .age = 24,
    .id = 1,
    ...
};
🌐
Reddit
reddit.com › r/askprogramming › is this a bad way to initialise a struct in c?
r/AskProgramming on Reddit: Is this a bad way to initialise a struct in C?
July 11, 2024 -

In my C program, I have a function that looks like this:

GameState cc_newGame(void) {
    // Create a new game state
    GameState* game = (GameState*)NULL;
    
    // Set the fields to their default values
    game->tick = 0;

    return *game;
}

Will creating a struct this way cause issues in my program?

EDIT: Thanks to a comment by u/whyeventrymore, I was able to figure out how to do this using malloc.

Top answer
1 of 5
6
At the root of this question is really a philosophical debate about putting stuff on the heap (malloc/free) vs on the stack. Heap allocations are nice in that you can determine at runtime how much space to allocate. That's vital if you want an array with a size you don't know until runtime. It isn't required if you have a struct of known, fixed size. The downside of heap allocations is that they're the pathway to memory leaks. When you take memory on the heap you are committing to freeing that memory exactly one time in the future. It's a violation to free it twice, and it's a memory leak to just never free it. The heap is also slower than the stack since the runtime has to find a block of memory that can be used. With that out of the way we can look at the two simple ways to modify your code. The first is to keep with the idea that game will be a GameState*. Rather than setting it to NULL you'll want to malloc some memory (and if you're being defensive, check that malloc didn't spit out NULL due to the allocation failing). Then once that GameState* is filled out you would return the pointer itself, making the return value of cc_newGame be GameState*. This setup winds up feeling a lot like a constructor in Java, always returning a pointer to an initialized struct. This can lead to a nice paradigm where no code ever has a GameState* pointer that points to an uninitialized struct so long as those pointers are only ever acquired by calling cc_newGame. However, it separates the responsibility of allocating the memory from the responsibility of freeing that memory. This can be managed, but if managed poorly it's a recipe for memory leaks. It also requires that GameState structs always live on the heap, which could be an annoying constraint down the line. The other simple modification is to keep the return value as GameState and do away with pointers entirely. Simply declare GameState game;, modify it with game.tick = 0;, and finally return game;. This approach allocates the GameState on the stack so you no longer have to bother with null pointers, memory lifespan, etc. It winds up being the simplest code to read. The downside of this approach is that a naive compiler doing exactly what's written will wind up making an extra copy: there's one GameState local to cc_newGame, but then if you call that function as GameState game = cc_newGame(); then that's saying to copy the return value into the variable local to the calling code. That downside isn't a big deal, though. First off the copy likely isn't actually that expensive, but more importantly it is likely to be optimized out in the first place! The C compiler's task is not to naively translate your code into assembly, but rather to generate assembly instructions that will give the same results "as if" it had done that naive translation. This "as if" rule is the foundation for countless optimizations, including one known as RVO where the extra copy in a scenario like this is just skipped. This sort of optimization is part of why you shouldn't worry about optimizing your code until you have profiled it--things that look like they ought to be expensive are often quite cheap. A third option is a bit of a hybrid between the two. This is to make cc_newGame take a GameState*parameter. This narrows the task that cc_newGame is doing, from allocating and initializing a GameState to just initializing a given GameState. The upside of this approach is that you allow cc_newGame to be agnostic to where the struct is located--the calling code could be GameState game; cc_newGame(&game); to have its GameState on the stack, or it could be GameState* game = malloc(sizeof(GameState)); cc_newGame(game);. The incoming struct might even be the memory where an old, no longer needed GameState lives (be sure to overwrite the entire struct!). The upside of this approach is that it leaves the greatest deal of flexibility to the calling code. The downside is that it leaves the greatest amount of work to the calling code, and it really needs a validation at the start to make sure a user didn't pass in NULL. All three of these are viable. If I were setting up a big codebase I would be inclined to pick the third option as the idiomatic approach for its flexibility. For a simple project to learn C I would probably pick the second option, or the first if part of the learning was how to deal with dynamically allocated memory.
2 of 5
4
The way you're initializing GameState in your C program won't work because game is set to NULL, meaning it doesn't point to an actual GameState struct. To fix it, you should allocate memory for game using malloc
🌐
Reddit
reddit.com › r/c_programming › correct way of dealing with memory in array of structs that contain character arrays?
r/C_Programming on Reddit: Correct way of dealing with memory in array of structs that contain character arrays?
April 22, 2024 -

Hey I'm fairly new to C, and just trying to wrap my head around the memory portion of having an array of structs which themselves contain character arrays. Here's some simple test code, could anyone tell me if I'm doing this right?

#include <stdio.h>    
#include <stdlib.h>    
    
int main() {    

typedef struct {    
    char *name;    
} Student;    

//allocate memory    
int totalElements = 3;    
Student *myArray = (Student*)malloc(totalElements * sizeof(Student));    
for (int i=0; i<totalElements; i++){myArray[i].name = malloc(3);}    

//set values    
myArray[0].name = "Joe";    
myArray[1].name = "Bob";    
myArray[2].name = "Kim";    

//print values    
for (int i=0; i<totalElements; i++){printf("%s\n", myArray[i].name);}    

//deallocate memory    
for (int i=0; i<totalElements; i++){free(myArray[i].name);}    
free(myArray);    

return 0;    
}
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>
🌐
Brown University
cs.brown.edu › courses › csci1310 › 2020 › notes › l05.html
CS 131/CSCI 1310: Fundamentals of Computer Systems
The arrow syntax (->) implicitly dereferences the pointer and then accesses the member. In other words, heap_allocated->i1 is identical to (*heap_allocated).i1. ... Like arrays, structures also have an initializer list syntax that makes it easy for you to set the values of their members when creating a struct.
🌐
Reddit
reddit.com › r/c_programming › struct initialization differences?
r/C_Programming on Reddit: Struct initialization differences?
August 13, 2023 -

Hello,

I've come across these different ways to build an struct. What are the differences between them? Specially the 1 and 3. I guess in the second approach the struct lives in the stack and when built with malloc it goes to the heap, but I don't understand third.

typedef struct {
    uint32_t a;
    uint8_t *b;
    uint32_t c;
} struct_a;

typedef struct {
    uint32_t aa;
    struct_a *bb;
} struct_b;

int main()
{
    // 1
    struct_b *b1 = malloc(sizeof(struct_b));
    
    // 2
    struct_b b2;
    
    // 3
    struct_b b3 = {0};
    memset(b3.bb, 0, sizeof(b3.bb));
    
    return 0;
}

🌐
Reddit
reddit.com › r/c_programming › can you move values from heap to stack space using this function?
r/C_Programming on Reddit: Can you move values from heap to stack space using this function?
May 20, 2025 -

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

char *moveFromHeap(char *oldValue) {
int n = strlen(oldValue) + 1;
char buf[n];
strncpy(buf, oldValue, n);
free(oldValue);
char* newreturn = buf;
return newreturn;
}

int main(void) {
char *randomString = strdup("COPY THIS STRING!");
char *k = moveFromHeap(randomString);
printf("k is %s\n", k);
return 0;
}

I found having to free all the memory at pretty annoying, so I thought of making a function that does it for me.

This works, but I heard this is invalid. I understand this is copying from a local space, and it can cause an undefined behaviour.

  1. Should I keep trying this or is this something that is not possible?

  2. Does this apply for all pointers? Does any function that defines a local variable, and return a pointer pointing to the variable an invalid function, unless its written on heap space?

Top answer
1 of 13
37
Rather than thinking about "heap" or "stack", you should really think about object lifetimes. That is: how long do you want the object to exist? An object created using malloc has a lifetime that ends when you call free on the allocation. An object created as a local variable has a lifetime that ends when execution leaves the scope in which the variable was declared. So take a look at your buf object. It is a local variable, so the array object's lifetime ends when that moveFromHeap function returns. The object literally does not exist past that point, and any attempt to use it (such as through the pointer you are returning from the function) is invalid. If you think of things in terms of lifetimes, then it is usually clear when you should use malloc and when you should not. It also demonstrates why malloc isn't necessarily something you want to avoid. It is what C gives you so that you can have an object's lifetime begin in one function and end in another. That is something you will often need.
2 of 13
6
char buf[n]; // buf is on the stack ... strncpy(buf, oldValue, n); free(oldValue); char* newreturn = buf; return newreturn; // return buf Yeah, that's not going to work, because as soon as you return, buf is popped off the stack, and now you've returned a pointer into an area that's going to be trashed by future use of the stack. Edit: also, does your program even work? $ cat x.c #include #include #include char *moveFromHeap(char *oldValue) { int n = strlen(oldValue) + 1; char buf[n]; strncpy(buf, oldValue, n); free(oldValue); char* newreturn = buf; return newreturn; } int main(void) { char *randomString = strdup("COPY THIS STRING!"); char *k = moveFromHeap(randomString); printf("k is %s\n", k); return 0; } $ gcc -o x -Wall -Wextra x.c $ ./x k is $ It doesn't seem to actually work as you imagine it does.
🌐
DEV Community
dev.to › davidhwangij › 5-25-til-c-basics-heap-memory-referencing-pointer-to-struct-1edo
5/25 TIL: C++ basics (heap memory, referencing, pointer to struct) - DEV Community
May 26, 2021 - You must delete (release/de-allocate) the memory in whenever you are dynamically allocating memory Ex) free(p) in C and delete [] p in C++ where p is an array · // allocates 20 bytes (5 * 4) of heap memory holding an int and assign that pointer to p p = (int *)malloc(5 * sizeof(int)); free(p); // C++ p = new int[5]; delete [] p;
Top answer
1 of 2
7
struct USER {
   int human_id_number;
   char first_name_letter;
   int minutes_since_sneezing;
} *administrator;

This isn't just a struct declaration, it's also a variable declaration... it's the same as:

struct USER {
   int human_id_number;
   char first_name_letter;
   int minutes_since_sneezing;
};

struct USER *administrator;

So, when you subsequently use sizeof(administrator), you'll get "the size of a pointer"... which is most likely not what you want.

You probably wanted to do something more like this:

struct USER {
   int human_id_number;
   char first_name_letter;
   int minutes_since_sneezing;
};

int main(void) {
    struct USER *administrator;

    administrator = malloc(sizeof(*administrator));
    /* - or - */
    administrator = malloc(sizeof(struct USER));

    /* check that some memory was actually allocated */
    if (administrator == NULL) {
        fprintf(stderr, "Error: malloc() returned NULL...\n");
        return 1;
    }

    /* ... */

    /* don't forget to free! */
    free(administrator)

    return 0;
}

sizeof(*administrator) and sizeof(struct USER) will both give you "the size of the USER structure", and thus, the result of malloc() will be a pointer to enough memory to hold the structure's data.

2 of 2
0
struct USER{
    int human_id_number;
    char first_name_letter;
    int minutes_since_sneezing;
} *administrator;

This defines administrator as a pointer variable. But, from the other code

administrator *newStruct = (administor*)malloc(sizeof(administrator));

It seems you want to use that as a type. To do so, you can make use of the typedef.

typedef struct USER{
    int human_id_number;
    char first_name_letter;
    int minutes_since_sneezing;
} administrator;

and then use

administrator *newStruct = (administrator *)malloc(sizeof(administrator));
Top answer
1 of 5
8

In this case, however, is it possible to create a new instance of this struct on the heap, or would I need to define a constructor? Is there a way to create things on the heap without the new operator?

As answered before, you can create a new instance on the heap either via new or with malloc.

Or, better yet: is it unnecessary for me to cling so tightly to the notion that I shouldn't define member functions for structs?

This is the more interesting question. The major (only?) difference between struct and class in c++ is the default access specifier. That is, struct defaults to public access and class defaults to private. In my opinion, this is the difference that should determine which of the two you use. Basically, if users should access the members directly, then it should be a struct.

If, for example, you have no member functions, then obviously the intention is for the object's members to be accessed directly and so it would be a struct. In the case of an object that is just a small private helper for the implementation of its outer class, as in your example, then even if it has member functions it is often clearest to allow the outer class access to its members and so it should be a struct. Often with these classes the implementation of the outer class is tightly coupled to the implementation of the inner class and so there is no reason to hide the one from the other.

So, for trivial (e.g. std::pair) objects or those whose use is limited (as in a private inner class) default access to members can be a good thing, and in these cases I would make them structs.

2 of 5
6

Even if you don't define a constructor, the compiler will create a default one and so you can use operator 'new':

Node *n = new Node;

AFAIAC, a struct is a class, except that its "publicness" default is reversed.