2013-08-07 2 views
4

Я новичок в C++, так что несите меня.Невозможно заполнить вектор внутри структуры

Я сделал структуру, которая выглядит следующим образом:

struct node{ 
    double startPoint; 
    double endPoint; 
    vector<node*> children; 

    void addChild(node *aNode){ 
     children.push_back(aNode); 
    } 
    void addPoints(double start, double end){ 
     startPoint = start; 
     endPoint = end; 
    } 
}; 

вниз линии в моей программе, у меня есть следующие:

vector<node*> data; 
.... 
node *temp = (node*)malloc(sizeof(node)); 
temp->addPoints(lexical_cast<double>(numbers[0]), lexical_cast<double>(numbers[1])); 
data[index]->addChild(temp); 

где «Index» является индексом вектора данных , вещи lexical_cast принимают эти числа от строки до удвоений.

Все работает до линии addChild(temp).

Терминал выплюнуть это:

First-chance exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1. 
Unhandled exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1. 

Но я понятия не имею, как иметь дело с этим.

+1

Есть ли причина, по которой вы используете 'malloc' вместо' new' для инициализации динамических переменных? – Kevin

+0

Что сказал отладчик? – pm100

ответ

0
  1. Я бы рекомендовал хранить node вместо node* в вашем векторе, так что вы не должны управлять памятью по своему усмотрению.
  2. это C++, так что вы не должны таНосом пространства для узла вы можете использовать новые так:
    Node * n = new Node();

  3. Нового гораздо лучше, потому что он вызывает конструктор и выделяет пространство, в то время как таНос просто последний.


Вы не показали большую часть вашего кода, но я бы реструктурировать класс узла, как это.

struct node{ 
    double startPoint; 
    double endPoint; 
    vector<node> children; 
    node(){} //add default constrcutor  
    void addChild(node aNode){ 
     children.push_back(aNode); 
    } 
    node & operator=(const node & n) { 
     startPoint = n.startPoint; 
     endPoint = n.endPoint; 
     return *this; 
    } 
    node(double start, double end): startPoint(start),endPoint(end){ 
    } //in c++ you have constructors which this should have been in the first place 
    //constructors are used for initializing objects 
}; 
  1. это лучше, что теперь вы не можете передать добавить ребенка nullptr избежать много проблем в вашем коде. У вас также есть конструктор. Теперь вы можете добавить такой узел.

node temp(start,end); data[index]=temp;

  1. У вас есть конструктор теперь который addPoints должен был в первую очередь
  2. Я также сделал оператор присваивания

Используя стиль кодирования, где вы выделяете память в стеке и выполняете Не используйте новые называется RAII и является важным методом для изучения C++ и производить исключение безопасный код, это главная причина, почему я выступаю не хранить node* «s

1

Что касается кода, я не вижу, вы никогда добавлять узлы в data массив

data.push_back(something); 

Так доступ data[index] бы из выделенной памяти массива. Он не будет жаловаться до тех пор, пока вы не попытаетесь установить память в этом блоке (с помощью addChild, пытающегося вставить элемент в массив children).

+0

это причина, по которой yr-код терпит неудачу, все остальные ответы говорят вам, что у вас есть что-то не так или что это может быть реализовано более современным способом. Уверенность никогда не используется malloc: используйте новый. Алос настоятельно рекомендую не иметь вектор голых указателей, лучше иметь вектор умных указателей – pm100

2

malloc выделяет некоторое пространство, но ничего не помещает в него. Он отлично работает для структур с простым старым данными (или тривиально инициализируемых классов), а в C это все, что у вас есть.

В C++ у вас есть классы, например std::vector, которые необходимо правильно построить, чтобы установить некоторые инварианты. Это делается с помощью прямого объявления для объектов с автоматическим временем хранения, но для объектов с динамическим распределением вам нужно использовать new вместо malloc.

Например,

std::vector<int> global; // (1) 
void foo() { 
    std::vector<int> local; // (2) 
    std::vector<int> *bad = malloc(sizeof(*bad)); // (3) 
    std::vector<int> *good = new std::vector<int>; // (4) 
    std::unique_ptr<std::vector<int>> better(new std::vector<int>); (5) 
} 
  1. прекрасно - этот глобальный инициализируется (я имею в виду конструктор вызывается) автоматически
  2. прекрасно - это локальная переменная также строится автоматически, и уничтожены правильно, как только foo выходы
  3. вы не можете использовать bad для чего-либо, потому что любой метод, который вы вызываете, предполагает, что конструктор уже запущен, и это не было
    • ok, вы не можете использовать bad для чего-либо без явного его построения с использованием места размещения. Вы не должны этого делать, но это подходит только тогда, когда вы делаете умные или хитрые вещи с пользовательским распределением.
  4. это нормально (но обратите внимание, вы должны удалить его вручную - foo имеет место утечка памяти)
  5. это лучше - вам не нужно убирать вручную

Обратите внимание, что ваш node класс также имеет.В этом случае он автоматически генерируется и ничего не делает, кроме вызова конструктора vector. Тем не менее, вам нужно его вызвать, что означает использование new для динамического выделения node.

Таким образом, ваша программа должна выглядеть примерно:

std::vector<std::unique_ptr<node>> data; 
... 
std::unique_pre<node> temp(new node); 
temp->addPoints(...); 
data[index]->addChild(temp); 

Примечание Я принимаю data[index] правомочно (я вижу от addChild вы знаете, как заполнить вектор уже), и что одного собственника модель, применяемая unique_ptr.

+0

yr окончательное предположение неверно, поэтому его приложение не работает – pm100

+0

Спасибо. Как вы можете сказать, что проблема - это вектор данных, а не вектор 'children'? – Useless

+0

Потому что он показал код, чтобы правильно настроить детей и вставить в него вещи (отдельно от malloc вместо нового - что, вероятно, сработало). Он не показывал тот же код для данных - поэтому я предполагаю, что его нет – pm100

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