pointer madness

I have a problem with pointers. I always used the references and have a hard time to adapt to that * or ** or ***.
I read the theory but could someone help me with practical task like this.

Suppose I have the following data structure:

1
2
3
4
5
 struct bd {
    int numpoints;    
    double  **coord;  
    double  s [3];  
};


Then we have this ones:

1
2
    double (**vrtx1) = nullptr,
    (**vrtx2) = nullptr;


And this read function is supposed to fill the variables with the data:

 
int readinput ( const char *inputfile, double ***pts, int * out )


and we fill struct bd **coord with this one:
1
2
3
4
  if (readinput ( inputfileA, &vrtx1, &nvrtx1 ))
    return (1);
  bd1.coord = vrtx1;
  bd1.numpoints = nvrtx1;


I am theoretically understand whats happening but I cannot practically grasp it and change to what I need.

And now what I need: I don't need to read any files, my coord will always be the 8 x 3 floating numbers: eight positions, each containing 3 floats. So how I could just fill **coord variable ? I would like to use double vector in this case. Remark: the code is written in C. And I need to reuse it in C++. I have 0 understanding about C.
thank you very much,

Last edited on
loop over 8 & 3 and put in values.
for(int i = 0; i < 8; i++)
for(int j = 0; j<3; j++)
{
coord[i][j] = something;
}

did you allocate memory for it? 2d memory requires getting the memory twice, once for the outer dimension, then a loop over that for each inner dimension.
its a lot easier to work in 1-d, and map to 2 d
the formula to access 1d as 2d is [max_cols*desired_row+desired_col]

pointers are like arrays in some ways, but you have to explicitly get the memory and give it back (malloc and free in C).
pointers are like references in some ways too, notably when passing them as parameters its very similar to a ref param.

if you know arrays, a pointer is just an array index into memory; its an integer. that is all it is at the simplest way to understand it. you need to get memory for it, or ask for an unused array location is what that really is. you need to give back (mark the location unused again) when done.
Last edited on
Thank you very much. So is it something like that?

double **cdata;
cdata = (float*) malloc(8*sizeof(float));

std::vector<std::vector<double>> cppdata;

for(int i = 0; i < 8; i++)
{
for(int j = 0; j<3; j++)
{
data[I][j] = cppdata[I][j];
}
}

Free(cdata);
C does not have vector. It was unclear what you were saying earlier.
If you want to do this in c++, say so. I was assuming you needed C only.

details matter. (I get sloppy in these posts too, but even so..)
data: does not exist, did you mean cdata?
I does not exist. did you mean i?

in C..
cdata = malloc(8*sizeof(float));
for(int j = 0; j < 8; j++)
cdata[j] = malloc(3*sizeof(float)); //8x3, you need to allocate the inner dimension.

now
cdata[1][2] is valid: it is a float.
and you have to loop to free the inside, then free the outside, reverse of above.

for one-d as 2-d:
float* cdata = malloc(24*sizeof(float));
and index
[1][2] is
cdata[1*3+2];//1 row * 3 columns + 2 columns, skip a row and 2 locations, however you want to say it.

I highly recommend you just use a vector in c++ and avoid memory management unless you really, really need it.
Last edited on
Thank you very much. Very unfortunately, I really need it and there is no other way.

So far I get the error: SEH exception with code 0xc0000005 thrown in the test body.

Maybe you can see the problem?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
double **cdata1 = nullptr;

cdata1 = (double **) malloc(24 * sizeof(double *));
    for (int32_t i = 0; i < 8; i++)
    {
        cdata1[i] = (double *) malloc(3 * sizeof(double));
    }

std::vector<std::vector<double>> cppdata1 = {{0, 0, 0},
                                                {1, 1, 1},
                                                {2, 2, 2},
                                                {3, 3, 3},
                                                {4, 4, 4},
                                                {5, 5, 5},
                                                {6, 6, 6},
                                                {7, 7, 7}};

    for (int32_t i = 0; i < 8; i++)
    {
        for (int32_t j = 0; j < 3; j++)
        {
            cdata1[i][j] = cppdata1[i][j];
        }
    }

0xc0000005 = access violation, most likely meaning you're accessing memory you don't have access to (e.g. out of bounds array, dereferencing invalid pointer).

I don't see a huge issue with your code excerpt, other than that you allocate excess memory (24 instead of 8 on line 3), and that you don't ever free your malloc'd memory. You might need to show a minimum example that reproduces your issue.
thanks. it is hard to show the whole code, but I will try to illustrate it more:

First, the structure, which serves as input to another function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
struct bd {
    int numpoints;    /**< Number of points defining the body.            */
    double **coord;  /** points' coordinates. */
    double  s [3];    /**< Support mapping computed last.                 */
};
[code/]

And my main problem is to transform my c++ vector to be given to **coord variable:

[code]

  double **cdata1 = nullptr, **cdata2 = nullptr;

    struct bd bd1{8, cdata1};
    struct bd bd2{8, cdata2};;

    double (**vrtx1) = nullptr,
    (**vrtx2) = nullptr;

    cdata1 = (double **) malloc(8 * sizeof(double *));
    for (int32_t i = 0; i < 8; i++)
    {
        cdata1[i] = (double *) malloc(3 * sizeof(double));
    }

    cdata2 = (double **) malloc(24 * sizeof(double *));
    for (int32_t i = 0; i < 8; i++)
    {
        cdata2[i] = (double *) malloc(3 * sizeof(double));
    }

    std::vector<std::vector<double>> cppdata1 = {{0, 0, 0},
                                                {1, 1, 1},
                                                {2, 2, 2},
                                                {3, 3, 3},
                                                {4, 4, 4},
                                                {5, 5, 5},
                                                {6, 6, 6},
                                                {7, 7, 7}};
    std::vector<std::vector<double>> cppdata2 = {{10, 10, 10},
                                                {11, 11, 11},
                                                {12, 12, 12},
                                                {13, 13, 13},
                                                {14, 14, 14},
                                                {15, 15, 15},
                                                {16, 16, 16},
                                                {17, 17, 17}};

    for (int32_t i = 0; i < 8; i++)
    {
        for (int32_t j = 0; j < 3; j++)
        {
            cdata1[i][j] = cppdata1[i][j];
        }
    }

    for (int32_t i = 0; i < 8; i++)
    {
        for (int32_t j = 0; j < 3; j++)
        {
            cdata2[i][j] = cppdata2[i][j];
        }
    }

/* Initialise simplex as empty */
    s.nvrtx = 0;

// the input should be given to the main function, which is actually written in C... can it be the problem?..

    dd = gjk(bd1, bd2, &s);

    printf("Distance between bodies %f\n", dd);


    for (int32_t i = 0; i < 3; i++)
    {
        free(cdata1[i]);
    }
    free(cdata1);

    for (int32_t i = 0; i < 3; i++)
    {
        free(cdata2[i]);
    }
    free(cdata2);
Topic archived. No new replies allowed.