0

Here is an example code of what I'm trying to achieve

typedef struct
{
  int x_pos, y_pos;
} A;

typedef struct
{
  A **arrayAp;
} B;

int main(void) {
    B B;
    int n = 10;
    A *array[n];
    B.arrayAp = array;
    for (int i = 0; i < 10; i++)
    {
    B.arrayAp[i] = malloc(sizeof(A));
    B.arrayAp[i]->x_pos = i;
    B.arrayAp[i]->y_pos = i + 1;
    }
    printf("%d",B.arrayAp[0]->x_pos);
}

It works as I want it to work. I can access elements of "array" using "arrayAp" pointer. But when I try to move some of this code to function for example:

A * makeAnArray()
{
    int n = 10;
    A *array[n];
    return &array;
}

and then assign value that it returns to "arrayAp"

B.arrayAp = makeAnArray();

Now I can't access first element of the array. Program just crash.

printf("%d",B.arrayAp[0]->x_pos);

But starting from second element everything works the same.

But the bigger problem I get when I try to move to function this code:

void initializeAnArray(B *B)
{
    for (int i = 0; i < 10; i++)
    {
    B->arrayAp[i] = malloc(sizeof(A));
    B->arrayAp[i]->x_pos = i;
    B->arrayAp[i]->y_pos = i + 1;
    }
}

Seems like it has no effect. When i'm trying to access array member through "arrayAp" pointer i'm getting some "random" values from memory.

typedef struct
{
  int x_pos, y_pos;
} A;


typedef struct
{
  A **arrayAp;
} B;

A * makeAnArray()
{
    int n = 10;
    A *array[n];
    return &array;
}

void initializeAnArray(B *B)
{
    for (int i = 0; i < 10; i++)
    {
    B->arrayAp[i] = malloc(sizeof(A));
    B->arrayAp[i]->x_pos = i;
    B->arrayAp[i]->y_pos = i + 1;
    }
}

int main(void) {
    B B;
    B.arrayAp = makeAnArray();
    initializeAnArray(&B);
    printf("%d",B.arrayAp[1]->x_pos);
}

Sorry for my poor English.

3 Answers 3

2

Your function should be:

A * makeAnArray()
{
    int n = 10;
    //A *array[n]; --> This is local to this function so won't work
    A *array = malloc(sizeof(A)*n); //--> Dynamic allocation
    return array;
}
Sign up to request clarification or add additional context in comments.

3 Comments

@ChLys - you could have passed int n as an argument.
I know, it just an example. I have a different program where n is calculated by a function. Just to make it simple I wrote this example.
Ah great - i will use this later for myself - simple and useful :)
2
A * makeAnArray()
{
    int n = 10;
    A *array[n];
    return &array;
}

You are returning a local pointer which dies after the function ends and causes UB.

Moreover return type of your function should be A** and you should allocate memory with *alloc and return to ensure every instance is different and is alive after the function call.

Possible fix

A * makeAnArray()
{
    int n = 10;
    A *array = malloc(n * sizeof(A));
    return array;
}

Comments

1

The part

A * makeAnArray()
{
    int n = 10;
    A *array[n];
    return &array;
}

is not going to work. The array array might be allocated on the stack, it cannot be accessed via the return value after termination of makeAnArray; the result is undefined behaviour.

1 Comment

C specifications never mention that stack must be used. You should say, it is usually implementted as stack.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.