Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error when passing pointer to array of structs

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

struct Point {
    double x;
};

void test(struct Point **a, int len)
{
    int i;

    printf("a = %p\n", a);
    for (i = 0; i < len; ++i)
        printf("%f\n", a[i]->x);
}

int main()
{
    int i;
    int len = 4;

    struct Point *P;

    P = malloc(len*sizeof(struct Point));

    for (i = 0; i < len; ++i) {
        P[i].x = i;
        printf("%f\n", P[i].x);
    }
    printf("&P = %p\n", &P);
    test(&P, len);

    return 0;
}

I am trying to pass an array of structs to a function (I want to pass a pointer to the array, not make a copy). When I try to use the array inside the function, I get an access violation. What is the correct way to do this? What am I doing wrong? a == &P, so it should work, right?

like image 976
user1801359 Avatar asked May 07 '15 14:05

user1801359


4 Answers

Why's you want a struct Point **? You can rewrite the same as

void test(struct Point *a, int len)
{
   //some stuff
    printf("%f\n", a[i].x);

}

and call it like

 test(P, len);

This way, IMHO, the requirement

I want to pass a pointer to the array

is also met#.


(#) NOTE: To be strict, here we pass the pointer to the first element of the array, however, the behaviour compares equal. Thanks to Mr. @alk for the comment.

like image 187
Sourav Ghosh Avatar answered Nov 16 '22 11:11

Sourav Ghosh


Passing &p to function test means that you are passing a pointer to the first element of an array of one element of type struct Point *. Therefore, only a[0] is valid (and hence a[0]->x) and all other a[i] are out of bound access. This will invoke undefined behavior.

Change a[i]->x to a[0][i].x or (*a)[i].x in test function.

Using pointer to pointer in this case is not worthy. This would be of worth using if passed pointer is to be modified in the function and that modification is expected to seen in the caller.

like image 25
haccks Avatar answered Nov 16 '22 12:11

haccks


The array should be passed using the parameter struct Point *a. When you increment a the pointer will move by sizeof(struct Point).

void test(const struct Point *a, int len)
{
    ...
}
like image 1
trojanfoe Avatar answered Nov 16 '22 10:11

trojanfoe


Other answers offer you better alternatives.But I'll put this here to help anyone (myself) understand why it is wrong.

enter image description here                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             

like image 1
Suvarna Pattayil Avatar answered Nov 16 '22 11:11

Suvarna Pattayil