Alexander George
Alexander George

Reputation: 871

Pointers to structures that contain pointers

Let's say I have a structure (datatype) as it follows:

typedef struct {
    int size;
    int *p;
} mystruct;

I declare a new structure as a pointer, because I want to pass it by reference to other functions:

mystruct *hello;

I have three questions:

  1. I understand that to access the size variable I have to do it with hello->size or (*hello).size, and that if I refer to p throuth hello->p I will only access the first position of the p array. But... How do I use an element inside that array? Would be correct something like (hello->p)[2]?

  2. Can I do realloc with the p array using that same notation (hello->p)?

  3. If I pass hello by reference to a function and want to modify the content of its variables and arrays... Is it enough to do hello->size = 3 to make the change effective in the whole program? How can I refer to the elements of the array p?

I'd appreciate any hint on the matter!

Upvotes: 1

Views: 709

Answers (3)

ThreeStarProgrammer57
ThreeStarProgrammer57

Reputation: 3044

edit

You edited your question, now p is a pointer, not an array.

  1. Yes, and you can omit the parenthesis.
  2. Yes, but you must have called malloc to allocate memory for it before calling realloc.

    edit

    Or you could initialize hello->p to NULL, so that calling realloc(hello->p, someSize) will return the same value as malloc(someSize).

    Either way, don't call realloc(hello->p, someSize) if hello->p is not initialized.

  3. Well, it will only affect the size member of the object that hello refers to. If you change the size member, you probably also want to realloc hello ->p so that it match the size of hello->size. You can access the element of p with hello->p[index]. You can take the address of one element with &hello->p[index].

edit 2

Answering your comment here.

If you declare an array of mystructure as you commented (mystructure hello[N];), you access it with hello[index].size and hello[index].p and hello[index1].p[index2]. This is because hello[index] is a struct;

To use the syntax hello[index1]->p[index2] (equivalent to (*(hello[index1])).p[index2]), you must declare an array of pointers to mystructure: mystructure * hello[N], but then you must allocate memory for each N pointers:

for (size_t i=0; i<N; ++i) {
    hello[i] = malloc(sizeof(mystructure));
    /* todo: initialize hello[i]->size and hello[i]->p */
}

original answer

Your struct definition won't compile because in the expression int p[size], size must be known at compile time. It cannot be the int size member, because it is a variable. You could if you declared int size as a const and give it a value.

  1. yes, and you can omit the parenthesis
  2. you cannot realloc p because you didn't called malloc to allocate memory for it.
  3. No, because of what I said first about your struct.

Upvotes: 3

Matthew Westrik
Matthew Westrik

Reputation: 89

  1. Yes, (hello->p)[2] or even just hello->p[2] will work to access elements of p.

  2. You can't realloc statically allocated arrays, only dynamically allocated ones. If you wanted to be able to realloc p you would have to change p to a pointer to an integer:

    typedef struct {
        int size;
        int *p;
    } mystruct;
    
  3. Yes. Remember that using a pointer to the struct is directly accessing the memory containing the struct. Any change you make to elements of the struct will be reflected to all places in the application that reference that memory location.

Upvotes: 0

Mantoine
Mantoine

Reputation: 642

  1. Yes, if hello is a pointer you can access your p array like that: (hello->p)[2].
  2. You won't be able to realloc your p array. p is a static array (due to the declaration using [size]). If you want to be able to realloc it you will need to declare it as int *p.
  3. You don't have to pass hello as a reference as long as it is already a pointer to a struct. If you modify it the struct will be modified everywhere.

Upvotes: 0

Related Questions