1

Here is my struct:

struct person{
    int id;
    char name[80];
    int age;
    char uni[80];
    int *block;
    int *friends;
    int f_count;
    int b_count;
};

Here is my function that gives error(Other functions are working correctly, I tested it, and the values passing to this function is correct, i tested it too.) This function giving this error (when running, no error while compiling): The instruction at 0xblabla referenced memory at 0xblabla. The memory could not be read.

void add_friend(struct person **p, int *p1, int *p2)
{
    int *newf1 = NULL;
    int *newf2 = NULL;

    (*p)[*p1].f_count += 1;
    newf1 = (int *)realloc((*p)[*p1].friends, ((*p)[*p1].f_count) * sizeof(int));

    if (newf1 != NULL)
    {
        (*p)[*p1].friends = newf1;
        (*p)[*p1].friends[((*p)[*p1].f_count) - 1] = *p2;
    }

    (*p)[*p2].f_count += 1;
    newf2 = (int *)realloc((*p)[*p2].friends, (*p)[*p2].f_count * sizeof(int));

    if (newf2 != NULL)
    {
        (*p)[*p2].friends = newf2;
        (*p)[*p2].friends[((*p)[*p2].f_count) - 1] = *p1;
    }
}
9
  • Not sure what your array of structures look like, but are you sure *p1 isn't accessing outside of the array bounds? Commented Jan 6, 2014 at 15:44
  • 1
    At first glance, changing (*p)[*i] to p[*i] should do the trick, and check for NULL pointers being passed. As your code now stands, you're accessing a pointer to struct person as though it was an array ((*p) dereferences first pointer, so you have *p, then you get [*i] offset), that can't be right. and as ever: don't cast void pointers returned by malloc / realloc Commented Jan 6, 2014 at 15:44
  • 1
    Have you stepped through the code in a debugger to see which is the offending line? Commented Jan 6, 2014 at 15:46
  • Welcome to SO. Before posting a question here you should learn how to use a debugger and try to find the error with the help of such a beast yourself. Commented Jan 6, 2014 at 15:46
  • mbratch- I'm sure it isn't accessing outside of array. Elias Van Ootegem - I will try and edit this comment with result. OldProgrammer and Jens Gustedt - I don't know how to use a debugger, where can i learn? Commented Jan 6, 2014 at 15:48

1 Answer 1

1

Update:
In response to your comment:

int main ( void )
{
    int i=1, j=2;//local vars
    struct person me;//a local, stack allocated, struct
    void add_person(struct person *p, int p1, int p2);//prototype
    //pass ADDRESS OF struct to function
    add_person(&me, i, j);
    return EXIT_SUCCESS;
}
void add_person(struct person *p, int p1, int p2)
{
    p->some_int = p2;//changes the struct we declared in main
    (*p).friends = newf2;//alt syntax: dereference pointer
}

Here, you see you have 2 ways of using a struct, either leave it as is, and use the indirection operator ->, or dereference it (*), and use direct access (.). Not all that hard, really...
For a better understanding, or at least a primer in pointers, I'd suggest this answer of mine, where I make an analogy between pointers, and a calendar. I've used this explanation to help a few people and all of them (up till now, no exception) found it quite helpful. It's a really simple way of thinking about pointers that isn't full proof (once you get into more complex stuff like decayed arrays of pointers to structs it doesn't quite stack up), but when learning, it should help you come to terms with the basics.


Ok, you have a pointer to a pointer. Great, so if you dereference that pointer, which you do (*p) you end up with a regular pointer to a struct. Great, but why would you then need the [*i], still? it's a pointer, not an array, unless [*i] is 0, you'll be accessing memory out of bounds, either write:

p[*i]->friends = newf2;//for example

or, if you want to make your life harder, still:

*(p+(*i)).friends = newf2;

That's just awful IMO, though...
Your approach (dereferencing + getting an index/offset) could perhaps work if you were to write this:

(*p)[0].friends = newf2;

But again, that's just making life difficult for yourself.
As is your passing pointers to ints to the function. Sure, sometimes you have to pass a pointer, but really, sending an int by copy isn't a lot of overhead:

void add_friend(struct person **p, int p1, int p2)
{//works fine
    p[i]->friends = newf2;
}
//call like so:
struct person **pers_array = calloc(10, sizeof(*pers_array));//alloc memory for pointers
for (int i=0;i<10;++i) pers_array[i] = malloc(sizeof *pers_array[i]);//alloc struct
add_friend(pers_array, 1, 2);

And as ever, don't cast void * in C + every malloc and or calloc has to have a free that goes with it

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

2 Comments

I didn't got it still but I will try to understand. Actually I need to use pointers like *p1 and *p2 since my mentor doesn't want me to use global variables. So is there no way pass this function *p1 and *p2 and use them as indexes? like p[*p1] ?
@user3163379: Passing an int to a function doesn't create a global, it creates a second local copy of that value, local to the called function's scope. Perhaps your mentor wanted you to use pointers for the struct, I'll add an example of how that can be done

Your Answer

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