Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic array in C — Is my understanding of malloc and realloc correct?

I am learning how to create dynamic 1D arrays in C. The code below tries to do the following:

  1. Using malloc, create a dynamic array of length 10, that holds values of type double.
  2. Set each entry of the array to j/100 for j = 0, 1,..., 9. Then print it out.
  3. Add an additional empty entry to the end of the array using realloc.
  4. 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

  1. Am I coding this right?

  2. 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?

like image 917
Legendre Avatar asked Oct 01 '12 15:10

Legendre


People also ask

What is a dynamic array in C?

Dynamic arrays are resizable and provide random access for their elements. They can be initialized with variable size, and their size can be modified later in the program. Dynamic arrays are allocated on the heap whereas VLAs are allocated on the stack.

Is realloc dynamic?

In other words, if the memory previously allocated with the help of malloc or calloc is insufficient, realloc can be used to dynamically re-allocate memory.

What is dynamic array explain it?

In computer science, a dynamic array, growable array, resizable array, dynamic table, mutable array, or array list is a random access, variable-size list data structure that allows elements to be added or removed. It is supplied with standard libraries in many modern mainstream programming languages.

What is the point of dynamic array?

Quick reference. A dynamic array is an array with a big improvement: automatic resizing. One limitation of arrays is that they're fixed size, meaning you need to specify the number of elements your array will hold ahead of time. A dynamic array expands as you add more elements.


2 Answers

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.

like image 166
John Bode Avatar answered Sep 20 '22 08:09

John Bode


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.

like image 36
Daniel Fischer Avatar answered Sep 21 '22 08:09

Daniel Fischer