1

Here is a quick test C program that I've coded to see how struct memory allocation works...

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

typedef struct _node {
    int kk;
    int zz;
} node;

node ** createNode(){
    node** res = (node**) malloc(sizeof(node*)*10);
    int i,j;
    for(i= 0;i<10;i++){
            res[i] = (node*) malloc(sizeof(node)*10);
            for(j=0;j<10;j++){
                    res[i][j].kk=33;
            }
    }
    return res;
}

int main(void) {
    node ** g = createNode();
    printf("%d",g[0][0].kk);



    return 0;
}

This program prints the value "33". Now this has become obvious to me, but reflecting on it, I don't understand why...

Now that I think about it, shouldn't the variable g be of type node *** ?

And the print statement look something like printf("%d",g[0][0]->kk); ?

Where in the second version, I've essentially done the same thing as my original code, but I have a pointer to a node instead of the actual node.

What is the difference between the two in terms of the first being statically allocated (I think) and the second being dynamically allocated... and shouldn't the node values I created in my createNode() function be destroyed once outside the scope of that function?

Just a little confused is all :S I need someone to clarify this for me, what is the difference between node** and node***

Jimmy Huch
  • 4,400
  • 7
  • 29
  • 34
  • 1
    If you ever type 3 stars in a row, you should step back and think about redesigning your code or putting in another abstraction. – user2357112 Nov 23 '13 at 05:08

1 Answers1

1

Let's use a simpler function to make samples. For example we want to create a function which will be allocate memory for integer and assign some value. The function does the same thing as your one.

int* createInt() {
    int *res = malloc(sizeof(int));
    *res = 5;
    return res;
}

This function creates a pointer and allocate dynamic memory for int. After this the function returns an address of memory where the int is but the res pointer won't exist. By the way look at this answer to similar question, it's worth reading.

As you understand in main function you use

int *myInt = createInt();

Because you want to assign an address of allocated memory to pointer to deal with that and free after all.

But you could do this

int** createInt() {
    static int *res;
    res = malloc(sizeof(int));
    *res = 5;
    return &res;
}

And in main

int **myInt = createInt();

Here you do the same things as above but create static pointer so it is retained from one call of the function to another. So you can return an address of this pointer. It will point to actual data after function ends.

As mentioned in comments my code isn't safe because if you call this function twice it leads to memory leak. You could do

int* createSingletonInt() {
    static int *res;
    if (res != NULL) {
        return res;
    }
    res = malloc(sizeof(int));
    *res = 5;
    return res;
}

That can be useful if you want to deal with the same int. And more useful if you deal with something but not int :>

I think it can be applied to your example.

Community
  • 1
  • 1
Deck
  • 1,969
  • 4
  • 20
  • 41
  • Careful there! That second `createInt` example **does not work**. You're returning the address of an automatic variable; the returned pointer is indeterminate, and almost anything you try to do with it is undefined behavior. If you call another function, the storage will probably be overwritten. – user2357112 Nov 23 '13 at 05:07
  • I return address of static variable, the behavior is defined. For example [this](http://stackoverflow.com/questions/453696/is-returning-a-pointer-to-a-static-local-variable-safe) question. But yes if we call my function twice it leads to memory leak. – Deck Nov 23 '13 at 05:13
  • Oh, it's static. That's defined, though not particularly useful. – user2357112 Nov 23 '13 at 05:15