简体   繁体   中英

Write a function to malloc double pointer

I need to write a function that creates a double pointer using malloc.

This is how I declared my double pointer as I normally would:

double **G; //Create double pointer to hold 2d matrix

*G = malloc(numNodes * sizeof(double*));
for(i = 0; i < numNodes; i++)
{
    G[i] = malloc(numNodes*sizeof(double));
    for (j = 0; j < numNodes; j++)
    {
        G[i][j] = 0;
    }
}

Now I tried replacing it with:

double **G;
mallocDoubleArr(G, numNodes);

With the function being:

void mallocDoubleArr(double **arr, int size)
{
    int i, j;

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

    for(i = 0; i < size; i++)
    {
        arr[i]= malloc(size*sizeof(double));
        for (j = 0; j < size; j++)
        {
            arr[i][j] = 0;
        }
    }
}

Why doesn't this work?

You need one more "indirection", in other words pass G by reference like a pointer to a pointer to a pointer to float:

void mallocDoubleArr(double ***arr, int size);

And then call it as

mallocDoubleArr(&G, numNodes);

Modify mallocDoubleArr accordingly, like for example

(*arr)[i] = malloc(size*sizeof(double));

C is call-by-value. In

double **G;
mallocDoubleArr(G, numNodes);

you are passing an uninitialized variable to mallocDoubleArr. It may be zero, it may be something else, but it almost certainly isn't something that mallocDoubleArr can assign to.

We can change the code, and the function's definition, to pass in G's address, but then you're dealing with yet another level of pointer. That might make it harder to understand the code. If that really isn't a requirement, I'd propose instead to have mallocDoubleArr return a double**.

double **G;
G = mallocDoubleArr(numNodes);

double **mallocDoubleArr(int size)
{
    int i, j;
    double **arr;

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

    /* continue with old code */

    return arr;
}

[edit: bstamour's post was made while I was writing mine. Sorry for any overlap.]

For starters, you need to change the line

*G = malloc(numNodes * sizeof(double*));

to

G = malloc(numNodes * sizeof(double*));

(you can't dereference a pointer safely until you've assigned something to it.)

Secondly, your function modifies the pointer passed in, so you need a pointer to it. Your signature should instead by

void mallocDoubleArr(double ***arr, int size)

and you will need to add the relevant indirections in your code to access the pointer that the pointer is pointing to.

A lot of confusion for beginners working with pointers comes from, in my opinion, thinking that they are something different than regular old variables. Pointers, like ints, floats, etc. are just variables that live on the stack: they have addresses, and they are passed to functions the same way. If you want to change a variable (int, float, pointer, etc) in a function, you need to pass a pointer to it. There is no difference in this regard.

I use for matrix operations code like following for allocating and freeing.

int **inputMatrix, i, j;
Grid myGrid = *grid;

inputMatrix = (int *) calloc (myGrid.num_nodes, sizeof(int*));
for(i=0; i < myGrid.num_nodes; i++){
    inputMatrix[i] = calloc(myGrid.num_nodes, sizeof(int));
    for(j=0;j<myGrid.num_nodes;j++){
        inputMatrix[i][j] = 0;
    }
};

for(i=0; i < myGrid.num_nodes; i++){
    free(inputMatrix[i]);
}
free (inputMatrix);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM