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.

Answer from paxdiablo on Stack Overflow
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.

🌐
Reddit
reddit.com › r/cs50 › how can malloc allocate structs?
r/cs50 on Reddit: How can malloc allocate structs?
January 2, 2022 -

I am currently on lecture 5 of cs50 course. So in it while implementing linked lists, after declaring a struct called "node", we malloc a node..like this:

node *n = malloc(sizeof(node));

And then after that, we treat it as if n is actually pointing to a node and we use operations like

n->Number and n->Next

But malloc only really allocates the amount of memory needed for a node right? We have not yet properly declared a node like we declare other structures like int v = 10 or char l = 'j';

Im sorry but I got slightly confused on this part..

Top answer
1 of 2
3
There isn't any further formatting or anything else needed in C to create a variable, you just need a space in memory big enough to hold it and a name that can reference it. The call to malloc reserves a space in memory that will hold your structure and returns a pointer to it, so once that call completes n is a valid pointer to a node structure. The node structure doesn't have valid data in it yet, so we probably want to initialize it to something reasonable with statements like: n->Number = 0; n-Next = NULL; This is exactly what the initializer function in a language like Java or C++ does when you call new Node. In C you need to do those steps yourself. You're also free to skip those steps if they aren't necessary in your context. You're also free to skip those steps when they are necessary and introduce a bug into your program.
2 of 2
2
node *n = malloc(sizeof(node)); |------| |------------------| A B Part A: Here you declare a pointer to a node "We have not yet properly declared a node like we ....." Part B: Here you allocate the memory sufficient to hold the data of a node. After this you have some memory that can hold a node and a pointer that directs you to that memory location. When you then want to see individual elements of that node struct you ask C to go to that location and look at that memory, C knows you are talking about a "node" since you already declared n as a pointer to a node so C knows what to expect to see at that location. This might not be 100% technically correct but I think it is pretty close and that is what makes me grasp pointers and malloc :)
Discussions

Question regarding struct, String and Malloc
I set values in a struct that is simply created as a global. Using the 'name.variable' syntax all works as expected, simple. I also created a pointer to a struct and the 'pointer->variable' syntax works as expected for String, bool, and int. Again, all good. Lastly, I used Malloc to get a chunk of ... More on forum.arduino.cc
🌐 forum.arduino.cc
19
0
March 12, 2022
Structs???? Malloc??? Pointers to Malloc and Structs??
I'm learning C++ right now and I am having a very hard time understandind structures, dynamic memory, and pointers to the latters. I understand this is how you write a pointer: ... though I'm not sure how you are supposed to use syntax for malloc, it's confusingint array[10] = (10 * sizeof(int); ... More on cplusplus.com
🌐 cplusplus.com
June 6, 2014
Best practice on allocating memory for a struct that has dynamic array members
Right now, the for loop is always printing the same value. You also need to free(ms->my_arr); Every malloc will have a corresponding free. More on reddit.com
🌐 r/C_Programming
21
3
February 29, 2024
How can I return a struct from a function?
Nothing special about it. struct foo { int i; }; struct foo bar() { struct foo s = { 1 }; return s; } More on reddit.com
🌐 r/C_Programming
45
29
December 25, 2023
🌐
University of Toronto
cs.toronto.edu › ~heap › 270F02 › node31.html
But first, structs and malloc
Given our declarations above, we ... n3->data = 3; n3->next = NULL; /* <-- indicates end of list */ malloc allocates sizeof(struct node) bytes, and returns a void pointer to it, which we cast to struct node *. Under some conditions malloc could fail to allocate the required ...
🌐
Delft Stack
delftstack.com › home › howto › c malloc struct
How to Allocate Struct Memory With malloc in C | Delft Stack
February 12, 2024 - Additionally, it explores scenarios ... to zero in C. malloc is the core function for dynamic memory allocation in C that takes a single integer argument representing the number of bytes to be allocated....
🌐
Nyu-cso
nyu-cso.github.io › notes › 06-struct-malloc.pdf pdf
Struct, malloc Jinyang Li
Conceptual view of a C program’s · memory at runtime · • Separate memory regions for global, local, and · malloc-ed. ..... ... Static data · (global variables) Heap · (for malloced data) Stack · (for local variables) We will refine this simple view · in later lectures · Linked list · typedef struct { int val; struct node *next; }node; val:5 ·
🌐
W3Schools
w3schools.com › c › c_memory_struct.php
C Structures and Dynamic Memory
This is useful when you don't know ... program where the number of cars is not fixed). You can use the malloc() function to allocate memory for a struct pointer:...
🌐
Swarthmore College
cs.swarthmore.edu › ~newhall › cs31 › resources › C-structs_pointers.php
CS31: Intro to C Structs and Pointers
To allocate Heap memory, call malloc passing in the total number of bytes of contiguous heap memory you want to allocate. malloc returns the base address of this heap memory to the caller or NULL on error. int *p; p = (int *)malloc(4); // allocate 4 bytes of heap memory and assign addr to p *p = 6; // the heap memory p points to gets the value 6 malloc's return type is a bit odd.
Find elsewhere
🌐
Programiz
programiz.com › c-programming › examples › structure-dynamic-memory-allocation
C Program to Store Data in Structures Dynamically
#include <stdio.h> #include <stdlib.h> struct course { int marks; char subject[30]; }; int main() { struct course *ptr; int noOfRecords; printf("Enter the number of records: "); 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 %d", (ptr + i)->subject, &(ptr + i)->marks); } printf("Displaying Information:\n"); for (int i = 0; i < noOfRecords; ++i) { printf("%s\t%d\n", (ptr + i)->subject, (ptr + i)->marks); } free(ptr); return 0; }
🌐
Quora
quora.com › How-do-I-malloc-an-array-of-structs-in-C
How to malloc() an array of structs in C - Quora
Answer (1 of 3): Let’s say you have defined a struct X, and you want to allocate an array of N of these structs. Then, [code]struct X *pArray = malloc(sizeof(struct X) * N); if (pArray) { // Access elements using pArray } [/code]It’s really that simple. You can use pArray with square bracket ...
🌐
GeeksforGeeks
geeksforgeeks.org › c language › how-to-dynamically-create-array-of-structs-in-c
How to Dynamically Create Array of Structs in C? - GeeksforGeeks
July 23, 2025 - To dynamically create an array of structs, we can use the malloc() function to dynamically allocate structs into the array of the given size.
🌐
Tenouk
tenouk.com › cpluscodesnippet › usingmallocnstruct.html
The malloc() C function and struct data storage - the dynamic memory allocation
The malloc() C function and struct data storage program example to demonstrate the dynamic memory allocation
🌐
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....
🌐
Quora
quora.com › With-nested-structs-in-C-when-you-malloc-the-outer-struct-does-that-automatically-malloc-the-inner-struct
With nested structs in C, when you malloc the outer struct, does that automatically malloc the inner struct? - Quora
Answer (1 of 5): As long as the inner struct is defined with static elements, yes. [code]struct outer { long min; long max; struct inner { size_t size; long data[100]; } }; /* statically allocates whole thing */ struct outer minmax; /* dynamically allocates w...
🌐
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...
🌐
C-pointers
c-pointers.com › malloc_ptr › dp_malloc_ptr › structures_dp.html
Malloc struct Double pointer - C Pointers Tutorials
struct ABC { int a; int b; int c; }; struct ABC **ptr; Step 3 : Create One single pointer · ptr = malloc( sizeof(struct ABC *) ); Allocates 8 Bytes of memory in heap · ptr points to array of single pointers · In this case, array has one single pointer · sizeof(ptr) is 8 Bytes ·
🌐
Scaler
scaler.com › home › topics › pointer to structure in c
Pointer to Structure in C - Scaler Topics
June 20, 2022 - However, the declaration for a pointer to structure only allocates memory for pointer NOT for structure. So to access the member of structure, we must allocate memory for structure using malloc() function and we could also give the address of the already declared structure variable to the structure pointer.
🌐
Cardiff University
users.cs.cf.ac.uk › Dave.Marshall › C › node11.html
Dynamic Memory Allocation and Dynamic Structures
Dynamic allocation is a pretty unique feature to C (amongst high level languages). It enables us to create data types and structures of any size and length to suit our programs need ... The Function malloc is most commonly used to attempt to ``grab'' a continuous portion of memory.
🌐
HowStuffWorks
computer.howstuffworks.com › tech › computer software › programming
Dynamic Data Structures: Malloc and Free - The Basics of C Programming | HowStuffWorks
March 8, 2023 - The (int *) typecast converts the generic pointer returned by malloc into a "pointer to an integer," which is what p expects. The free statement in C returns a block to the heap for reuse. The second example illustrates the same functions as the previous example, but it uses a structure instead ...
🌐
Cplusplus
cplusplus.com › forum › beginner › 134883
Structs???? Malloc??? Pointers to Malloc and Structs??
June 6, 2014 - Also... malloc cannot return an array because it doesn't know it's allocating an array -- it's just allocating a clump of memory. Therefore, it'll return a pointer which contains the address of the memory it just allocated for you.