I have a struct
typedef struct
{
int size; //size of array
int array*
}
How do I allocate memory for the int array using the size variable and malloc
?
I have a struct
typedef struct
{
int size; //size of array
int array*
}
How do I allocate memory for the int array using the size variable and malloc
?
The answer to your question will depend on whether you are declaring a struct
or a pointer to struct
. In the event you declare a struct (e.g. mystruct s
), then you only need to allocate memory for s.size
elements in s.array
. e.g.:
typedef struct mystruct {
int size;
int *array;
} mystruct;
...
mystruct s;
s.size = 5;
/* allocating array based on size */
s.array = malloc (s.size * sizeof *s.array);
if (!s.array) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
note: you must validate your allocation succeeded and malloc
actually returned a valid address each time you call malloc
. (you can create a function that does this to cut down on the typing). You then only need free s.array
when you are done.
However, if you declare a pointer to struct
(e.g. mystruct *msp = NULL;
) you now have to allocate memory for both msp
and msp->array
. Example:
mystruct *msp = NULL;
msp = malloc (sizeof *msp);
if (!msp) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
msp->size = 5;
/* allocating array based on size */
msp->array = malloc (msp->size * sizeof *msp->array);
if (!msp->array) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
You must free
both when you are done.
The following is a quick example showing the allocation, use and freeing of memory for array
in both circumstances:
#include <stdio.h>
#include <stdlib.h>
typedef struct mystruct {
int size;
int *array;
} mystruct;
int main (void) {
size_t i = 0;
size_t nelements = 0;
int rd = 0;
/*
* declaring a struct mystruct
*/
mystruct s;
s.size = 5;
/* allocating array based on size */
s.array = malloc (s.size * sizeof *s.array);
if (!s.array) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
/* fill array */
for (rd = 0; rd < s.size; rd++)
if (scanf ("%d", &s.array[nelements]) == 1)
nelements++;
for (i = 0; i < nelements; i++)
printf (" s.array[%zu] = %d\n", i, s.array[i]);
/* free allocated memory */
free (s.array);
putchar ('\n');
/*
* declaring a pointer to mystruct
*/
mystruct *msp = NULL;
/* allocate memory for msp (mystruct pointer) */
msp = malloc (sizeof *msp);
if (!msp) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
msp->size = 5;
/* allocating array based on size */
msp->array = malloc (msp->size * sizeof *msp->array);
if (!msp->array) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
/* fill array */
rd = 0;
nelements = 0;
for (rd = 0; rd < msp->size; rd++)
if (scanf ("%d", &msp->array[nelements]) == 1)
nelements++;
for (i = 0; i < nelements; i++)
printf (" msp->array[%zu] = %d\n", i, msp->array[i]);
/* free allocated memory */
free (msp->array);
free (msp);
return 0;
}
Example Use/Output
$ printf "2\n4\n6\n8\n10\n12\n14\n16\n18\n20\n" | ./bin/struct_alloc_int
s.array[0] = 2
s.array[1] = 4
s.array[2] = 6
s.array[3] = 8
s.array[4] = 10
msp->array[0] = 12
msp->array[1] = 14
msp->array[2] = 16
msp->array[3] = 18
msp->array[4] = 20
Memory Error Check
In any code you write that dynamically allocates memory, it is imperative that your use a memory error checking program. For Linux valgrind
is the normal choice. There are so many subtle ways to misuse a block of memory that can cause real problems, there is no excuse not to do it. There are similar memory checkers for every platform. They are simple to use. Just run your program through it.
$ printf "2\n4\n6\n8\n10\n12\n14\n16\n18\n20\n" | valgrind ./bin/struct_alloc_int
==20515== Memcheck, a memory error detector
==20515== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==20515== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==20515== Command: ./bin/struct_alloc_int
==20515==
s.array[0] = 2
<snip>
msp->array[4] = 20
==20515==
==20515== HEAP SUMMARY:
==20515== in use at exit: 0 bytes in 0 blocks
==20515== total heap usage: 3 allocs, 3 frees, 56 bytes allocated
==20515==
==20515== All heap blocks were freed -- no leaks are possible
==20515==
==20515== For counts of detected and suppressed errors, rerun with: -v
==20515== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
int *ptr;
ptr = malloc(sizeof *ptr * size);
//can now reference ptr[0], ptr[1], ... ptr[size-1].
What the above code does: When you allocate memory for an int array, you allocate 4 bytes of memory (sizeof(int)) for each element you need. So when you malloc, you malloc the size of the element multiplied by the number of elements you need.
You can create a function for initializing the struct, you can create one like this:
typedef struct {
int size; //size of array
int *array;
} mystruct;
mystruct * create_mystruct(int size) {
mystruct * st = (mystruct*) malloc(sizeof(mystruct));
st->size = size;
st->array = (int *) malloc(sizeof(int) * size);
return st;
}
Here is a working idone as an example.