3

I want to dynamically allocate 1 dimension of a 2D array (the other dimension is given). Does this work:

int NCOLS = 20;

// nrows = user input...

double *arr[NCOLS];

arr = (double *)malloc(sizeof(double)*nrows);

and to free it:

free(arr)
Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
user308827
  • 21,227
  • 87
  • 254
  • 417

3 Answers3

6

Not quite -- what you've declared is an array of pointers. You want a pointer to an array, which would be declared like this:

double (*arr)[NCOLS];

Then, you'd allocate it like so:

arr = malloc(nrows * sizeof(double[NCOLS]));

It can then be treated as a normal nrows by NCOLS 2D array. To free it, just pass it to free like any other pointer.

In C, there's no need to cast the return value of malloc, since there's an implicit cast from void* to any pointer type (this is not true in C++). In fact, doing so can mask errors, such as failing to #include <stdlib.h>, due to the existence of implicit declarations, so it's discouraged.

The data type double[20] is "array 20 of double, and the type double (*)[20] is "pointer to array 20 of double". The cdecl(1) program is very helpful in being able to decipher complex C declarations (example).

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • Thanks! When I do this, I get the following error: error: invalid conversion from 'void*' to 'double (*)[1]' – user308827 Nov 08 '12 at 20:52
  • The code I have is: double (*arr)[NCOLS]; struct->arr = malloc(sizeof(double[NCOLS]) * nrows); – user308827 Nov 08 '12 at 20:55
  • 1
    @user308827: Are you compiling it as C code or C++? If it's C, there's no need for the cast, as I said above, if you're compiling it as C++, then you need to cast the result. In this case, you'd cast it to `(double (*)[NCOLS])`. – Adam Rosenfield Nov 08 '12 at 21:09
1

An example:

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

#define COLS 2

void func(int (**arr)[COLS], int rows)
{
    int i, j;

    *arr = malloc(sizeof(int[COLS]) * rows);
    printf("Insert number: \n"); 
    for(i = 0; i < rows; i++) 
        for(j = 0; j < COLS; j++) 
            scanf("%d", &(*arr)[i][j]);
    for(i = 0; i < rows; i++) 
        for(j = 0; j < COLS; j++) 
            printf("%d\n", (*arr)[i][j]);
}


int main(void)
{ 
    int (*arr)[COLS];

    func(&arr, 2);
    free(arr);
    return 0;
} 
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • Thanks! When I try to run this program, I get the error: error: invalid conversion from 'void*' to 'int (*)[2]' How do I rectify that? – user308827 Nov 08 '12 at 21:09
0

You have to allocate a new array for each element (each element is a pointer to an array) on the first dimension. You can use a loop for that:

for(i = 0; i < NCOLS; i++)
   arr[i] = (double *)malloc(sizeof(double)*nrows);

Do the same to free.

imreal
  • 10,178
  • 2
  • 32
  • 48