0

So I'm using an array to store sructs (struct is Path). Defined as such:

Path **array = malloc(items * sizeof(Path *));

Then each element is alloc'd:

for (i=0;i<items;i++) 
{
    array[i] = malloc(sizeof(Path *));
}

Later in the program variables are updated as such:

Path *path = array[id];
path->next_hop=-1;
path->weight=INT_MAX;

I then have a separate function to print the values of the array, taking the pointer to the first item in the array (array[0]) and the size of array as parameters, declared as such:

void PrintTable(Path *paths, int n)
{
    if(paths == NULL || n <= 0)
        return;
    printf("%s %8s %8s\n", "Net ID", "Weight", "Next Hop");
    for(int i = 0; i < n; i++)
    {
        Path *p = paths + i;
        printf("%d %8.2f %8d\n", vertices[i],p->weight, p->next_hop);
    }

}

When I was debugging I noticed that the stuct pointers seem to be in memory addresses with locations 0x000000000020 apart while in the loop the memory addresses being read are 0x000000000010 apart. Therefore by making this change:

Path *p = paths + i;

to

Path *p = paths + (2 * i);

It seems to work. Why is this? And how do I fix it?

1
  • Shouldn't Path *paths be Path *paths[]? Commented Jan 11, 2023 at 19:53

3 Answers 3

2

You have an array of pointers to Path, not an array of Path. So the argument to PrintTable should be Path **paths or Path *paths[], not Path *paths.

Then you can simply index it rather than using pointer arithmetic in the loop.

void PrintTable(Path *paths[], int n)
{
    if(paths == NULL || n <= 0)
        return;
    printf("%s %8s %8s\n", "Net ID", "Weight", "Next Hop");
    for(int i = 0; i < n; i++)
    {
        printf("%d %8.2f %8d\n", vertices[i], paths[i]->weight, paths[i]->next_hop);
    }

}
Sign up to request clarification or add additional context in comments.

6 Comments

Do not overlook array[i] = malloc(sizeof(Path *));, where the type of array[i] is Path *, so the size should be of *array[i] or Path.
Thanks but is there a way to do it without modifying the PrintTable function? (I am not allowed to change it)
@Nat569On You could change your array to be Path *array instead of Path **array.
@Barmar but isn't that for a single struct pointer, not an array of struct pointers?
Why use an array of struct pointers instead of an array of structs? That's what PrintTable expects. If you don't want to modify the PrintTable function, you have to make the data match what it expects.
|
0

You seem to be doing two contradictory things. You have this:

Path **array = malloc(items * sizeof(Path *));

which does not declare an array of Path structures. It declares an array of pointers to Path structures.

You then have this:

for (i=0;i<items;i++) 
{
    array[i] = malloc(Path *); // BUG
}

in an attempt to allocate all the structure pointers you need for your array. malloc(Path *) is nonsense, and I'm amazed your compiler let you do that. You probably want:

    array[i] = malloc(sizeof(Path));

You then have things like this, which are reasonable for an array of pointers to Paths:

Path *path = array[id];
path->next_hop=-1;
path->weight=INT_MAX;

But your PrintTable() function treats your array as an array of Paths, not an array of pointer to Paths.

@Barmar has just posted the fix for your PrintTable() function, which I won't repeat here.

Your compiler probably warned you about some of these issues.

1 Comment

Yes that was a mistake. I have sizeof(Path *) in my code.
0

One of the problems is the tendency to "know" what you're doing and tell the compiler that you want something that doesn't make sense...

array[i] = malloc(sizeof(Path *)); // space for a pointer where a struct is needed

Get used to a better syntax:

array[i] = malloc( sizeof *array[0] );

Allocate enough space to store an instance of what the pointer will be pointing at.

(Much less maintenance and fewer bugs caused by naming an incorrect datatype.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.