djwbrown
djwbrown

Reputation: 1131

Creating an array of pointers to structures - C++

I'm having trouble understanding arrays of pointers to structures. I created this simple example to try and understand them better. Although it compiles, I keep getting "BAD ACCESS" crashes (nonsense pointers) at the point shown below. Can anyone explain why this is wrong?

#include <iostream>
using namespace std;

struct complex_num {
    double real_part;
    double imag_part;
};

void init_complex(complex_num *element) {
    element->real_part = -1.0;             // <--- EXECUTION STOPS HERE.
    element->imag_part =  1.0;
}

int main(int argc, char *argv[]) {
    int n = 5;

    complex_num *array[n]; // Allocates for an array of n pointers to
                           // the complex_num structure, correct?

    for (int i = 0; i < n; i++) {
        init_complex(array[i]);
    }

    return 0;
}

I know there are better ways to do this. I know this is very C in style. Please don't suggest a different data structure. I'm curious specifically about arrays of pointers to structures. Thanks!

Upvotes: 3

Views: 5209

Answers (2)

Bharath Palaksha
Bharath Palaksha

Reputation: 39

yes, there is no memory allocated to the pointers you have declared. It doesn't point to any valid structure object

Upvotes: 1

codeling
codeling

Reputation: 11369

You did not allocate memory for your complex_num objects, only for an array with pointers to it. So when you call init_complex, it operates on a pointer to an invalid location.

Try this:

for (int i = 0; i < n; i++) {
    array[i] = new complex_num();
    init_complex(array[i]);
}

Your statement complex_num *array[n] creates an array of n pointers to complex_num. Meaning, the array can hold n pointers to complex_num; but the pointers themselves are still uninitialized. They point to random locations - every uninitialized primitive (to which pointers belong as well) in C++ will usually simply contain whatever value was in the memory location before the allocation. This will almost certainly lead to unexpected results, as there is no way (or at least no reasonably easy way) of telling where an uninitialized pointer points to.

So you'd have to make each pointer in the array point to some properly set up memory location containing complex_num; only after that you should access (read or write) the values in the complex_num where the pointer points to. To make it e.g. point to a dynamically allocated, new complex_num object, use the above code (notice the new keyword which does the dynamic allocation).

Side note: "Raw" pointers, pointing to dynamically allocated objects, like shown above, are tricky to handle (you should not forget to call delete after you are finished, otherwise you will leak memory), therefore the recommended practice is usually to use smart pointers (like std::shared_ptr, introduced with C++11).

Upvotes: 4

Related Questions