I am creating a dynamic structure using malloc. My struct looks like this:
typedef struct
{
int v=;
int t;
struct a *prev;//points to previous struct in same row
struct a *next;//points to next struct in same row
//Is this correct notation?
} a;
a **b;
During initialization, I do this:
for(i=0;i<d1;i++)
{
for(j=0;j<d2;j++)
{
if (j==0) //if first block, point to NULL
b[i][j]->prev = NULL;
else //else point to previous block.
b[i][j]->prev = *(b[i] + j - sizeof(b[i][j]));
}
}
I am getting error invalid type argument. What is wrong here? For prev, I am trying to first find address of the current block *(b[i]+j)
and to get address of previous block, subtracting the size of each block i.e. sizeof(b[i][j])
b[i][j]
is not a pointer. Hence, You cannot use:
b[i][j]->prev = NULL;
Use
b[i][j].prev = NULL;
Update
The links between the objects can be created using:
for(j=0;j<d2;j++)
{
// Fix the prev link
if (j==0) //if first block, point to NULL
b[i][j].prev = NULL;
else //else point to previous block.
b[i][j].prev = &b[i][j-1];
// Fix the next link
if (j==d2-1) //if last block, point to NULL
b[i][j].next = NULL;
else //else point to next block.
b[i][j].next = &b[i][j+1];
}
I'm guessing that you want elements within each row to be dlinked but not against previous rows. My take:
void
fill(void)
{
int d1;
int d2;
a **b;
a *x;
int i;
int j;
d1 = 10;
d2 = 20;
b = calloc(d1 * d2,sizeof(a));
x = &b[0][0];
for (i=0; i<d1; i++) {
x->prev = NULL;
x->next = x + 1;
for (x++, j=1; j<d2; j++, x++) {
x->prev = x - 1;
x->next = x + 1;
}
x[-1].next = NULL;
}
}
UPDATE:
Pointer arithmetic when you add n to a pointer. If n is 1, you are not adding 1 to the address, you're adding sizeof(*ptr). Consider that all of the following are equivalent:
int *xp;
int n;
(A1) xp += n;
(A2) xp = (int *) (((unsigned long) xp) + (n * sizeof(int)))
(A3) xp = &xp[n];
(A4) xp = (int *) (((char *) xp) + (n * sizeof(int)))
Stare at this for a while until you truly understand why this is true. This is key. The value you add to a pointer should exactly equal the index value of an array of the same type.
Your code is broken in a few ways:
- You need to replace b[i][j]->prev
with b[i][j].prev
because b[i][j]
already fully dereferences the pointer [this was pointed out by others]
- When you're doing *(b[i] + j - sizeof(b[i][j])
, I'm not even sure what you'll get.
- You want &b[i][j-1]
(A3). Your code [if it works at all], probably produces &b[i][j-18]
.
- This is because your mixing pointer arithmetic and byte sizes (e.g. you're doing a mashup of (A1), (A2), and (A3) above--you can use one or the other but not both/all at the same time)
My code only needs a single pointer that is set at the beginning because it's incremented by 1 in the inner loop.
Note that after finishing the "j loop", x == &b[i][d2]
which is also &b[i+1][0]
. That might help make it clearer.
Also, I handle the j==0 case before the inner j loop and post fix the "j==d2-1" case afterwards. That way, no if's inside the inner loop and why it starts at 1, not 0
Note that x[-1].next
(case A3) is (x - 1)->next
(case A1)
Here the loops are recoded slightly to be a bit simpler/faster. It assumes an addition variable: a *ep;
for (i=0; i<d1; i++) {
x->prev = NULL;
x->next = x + 1;
ep = x + d2;
for (x++; x<ep; x++) {
x->prev = x - 1;
x->next = x + 1;
}
x[-1].next = NULL;
}
I think you've got enough to get your code working. After that, try to understand your code vs mine and why both work the way they do. Doing this will give you a leg up on dealing with pointers and pointer arithmetic and it will soon be as easy as indexing through an ordinary fixed size array. Happy Programming ...