Dynamic array in C — Is my understanding of malloc and realloc correct?
Solution 1
You're close.
In C (at least since the 1989 version of the standard), the cast before malloc
and realloc
is unnecessary, since C can convert values of type void *
to int *
without a cast. This is not true for C++, so based on the error you're getting, it sounds like you're compiling this code as C++ and not C. Check the documentation for VS2010 to determine how to compile code as C.
The following is my preferred style for writing a malloc
call:
double *data = malloc(10 * sizeof *data);
Since the type of the expression *data
is double
, sizeof *data
is equivalent to sizeof (double)
. This also means you don't have to adjust your malloc
calls if the type of data
changes.
As for the realloc
call, it's safer to assign the result to a temporary pointer value. realloc
will return NULL if it cannot extend the buffer, so it's safer to write
double *tmp;
...
tmp = realloc(data, 11 * sizeof *data);
if (!tmp)
{
// could not resize data; handle as appropriate
}
else
{
data = tmp;
// process extended buffer
}
Be aware that Microsoft's support for C ends with the 1989 version of the language; there have been two revisions of the language standard since then, which have introduced some new features and deprecated old ones. So while some C compilers support C99 features like mixed declarations and code, variable length arrays, etc., VS2010 will not.
Solution 2
1) Am I coding this right?
Mostly. But data = (double*)realloc(data,11*sizeof(double));
loses the reference to the allocated memory if realloc
fails, you should use a temporary pointer to hold the return value of realloc
and check whether it's NULL
(and you also ought to check the return value of malloc
).
2) Tutorials I found use malloc without putting the (double*) in front.
In C, malloc
returns a void*
that can implicitly be converted to any other pointer type, so no cast is needed (and widely discouraged because casting that can hide errors). Visual Studio apparently compiles the code as C++ where the cast is required.
Solution 3
In C, you should not cast the return value of malloc()
.
Also, it's a bad idea to encode the type in the malloc()
argument. This is a better way:
double* data = malloc(10 * sizeof *data);
Related videos on Youtube
Legendre
Updated on July 09, 2022Comments
-
Legendre almost 2 years
I am learning how to create dynamic 1D arrays in C. The code below tries to do the following:
- Using
malloc
, create a dynamic array of length10
, that holds values of typedouble
. - Set each entry of the array to
j/100
forj = 0, 1,..., 9
. Then print it out. - Add an additional empty entry to the end of the array using
realloc
. - Set the new entry to
j/100
and print out each entry again.
Testing:
double* data = (double*)malloc(10*sizeof(double)); for (j=0;j<10;j++) { data[j]= ((double)j)/100; printf("%g, ",data[j]); } printf("\n"); data = (double*)realloc(data,11*sizeof(double)); for (j=0;j<11;j++) { if (j == 10){ data[j]= ((double)j)/100; } printf("%g, ",data[j]); } free((void*) data);
Questions
Am I coding this right?
Tutorials I found use
malloc
without putting the(double*)
in front. E.g.,int *pointer;
pointer = malloc(2*sizeof(int));
This does not compile for me on Visual Studio 2010, Windows 7. The error message is
value of type void cannot be assigned to entity of type
int
.Why does it work for those tutorials and not for me? Am I right to guess that it is because the compilers they are using automatically fill in the
(int*)
for them in my example?-
Antti Haapala -- Слава Україні over 6 years"value of type void cannot be assigned to entity of type int" is not an error that a C compiler should produce. The problem is that you're using a C++ compiler. Make sure that your source file is named
<something>.c
.
- Using
-
Legendre over 11 yearsThis compiles. But Visual Studio 2010 warns that "value of type void cannot be used to initialize an entity of type double". Is it ok to just ignore the warning?
-
Legendre over 11 yearsThanks, that was very helpful.
-
vulcan raven almost 9 yearsUpdate: VS2015 supports C99 + partial C11 and option to for WinXP targets. So Microsoft continued the ISO C support in 2015.
-
Peter - Reinstate Monica about 3 years@Legendre I hope the message says "value of type void * cannot be used to initialize an entity of type double * ! (note the asterisks -- both source and destination are pointers, but of different types,something a C++ compiler must complain about).