2013-10-15 3 views
2

У меня возникли проблемы с пониманием массивов указателей на структуры. Я создал этот простой пример, чтобы лучше понять их. Хотя он компилируется, я продолжаю сбой «BAD ACCESS» (бессмысленные указатели) в точке, показанной ниже. Может ли кто-нибудь объяснить, почему это неправильно?Создание массива указателей на структуры - C++

#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; 
} 

Я знаю, что есть лучшие способы сделать это. Я знаю, что это очень C в стиле. Пожалуйста, не предлагайте другую структуру данных. Мне особенно интересно узнать о массивов указателей на структуры. Благодаря!

ответ

4

Вы не выделили память для своих complex_num объектов, только для массива с указателями на него. Поэтому, когда вы вызываете init_complex, он работает с указателем на недопустимое местоположение.

Попробуйте это:

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

Ваше заявление complex_num *array[n] создает массив указателей на п complex_num. Значение, массив может содержать nуказатели to complex_num; но сами указатели все еще неинициализированы. Они указывают на случайные местоположения - каждый неинициализированный примитив (к которому также относятся указатели) в C++ обычно просто содержит любое значение в ячейке памяти перед распределением. Это почти наверняка приведет к неожиданным результатам, так как нет способа (или, по крайней мере, не достаточно простого способа) указать, на что указывает неинициализированный указатель.

Таким образом, вам нужно сделать каждый указатель в точке массива подходящим образом настроенной ячейкой памяти, содержащей complex_num; только после этого вы должны получить доступ (прочитать или записать) значения в complex_num, на которые указывает указатель. Чтобы сделать это, например, укажите динамически выделенный новый объект complex_num, используйте приведенный выше код (обратите внимание на ключевое слово new, которое выполняет динамическое распределение).

Сторона примечания: указатели «Raw», указывающие на динамически выделенные объекты, как показано выше, являются сложными для обработки (вы не должны забывать позвонить delete после того, как вы закончите, иначе вы будете утечка памяти), поэтому рекомендованная практика обычно используют интеллектуальные указатели (например, std :: shared_ptr, введенные с C++ 11).

1

Да, для указателей, которые вы указали, нет памяти. Он не указывает на какой-либо действительный объект структуры

Смежные вопросы