Не удается правильно вернуть вектор, находящийся в структуре C++

В настоящее время у меня есть структура p, которая содержит вектор другой структуры с именем pg. Вот структура процесса:

struct p{
int i;
int s;
vector<pg*> pT;

void addP(struct pg* nP){
    pT.push_back(nP);
}

};

Где-то еще в программе я создаю новую структуру p, выполнив:

struct p *p1= (struct p*) malloc(sizeof(struct p));

а затем присвойте значения идентификатору и размеру. Я хочу добавить новую страницу в вектор pT структуры. Поэтому я решаю, что могу сделать p1-> addP(makeP()), где makeP возвращает указатель на структуру pg, pg*.

Вот ссылка на то, что gdb показывает, когда он segfaults. Также упоминается, что это происходит в строке push_back. http://imgur.com/KZOGnI9

Что-то не так с указателями? Или я неправильно выделяю память для вектора?


person user3261941    schedule 31.03.2016    source источник
comment
Этот вектор голых указателей всегда даст вам гадость.   -  person Bathsheba    schedule 31.03.2016
comment
malloc не вызывает конструктор process. Поэтому ваш pageTable построен неправильно, только зарезервирована память. Попробуйте new!   -  person knivil    schedule 31.03.2016
comment
Вы не должны использовать malloc для создания нового process - конструктор для pageTable не будет вызываться - используйте new - в конце концов, это C++...   -  person Paul R    schedule 31.03.2016
comment
@Bathsheba Не так много, как выделение объекта вектором с использованием malloc.   -  person juanchopanza    schedule 31.03.2016
comment
Лучше используйте new вместо malloc() всякий раз, когда задействованы сложные классы C++, такие как std::vector.   -  person πάντα ῥεῖ    schedule 31.03.2016
comment
@juanchopanza Да, действительно, это доставит вам много хлопот!   -  person Bathsheba    schedule 31.03.2016
comment
Вы абсолютно уверены, что вам нужно выделить proc динамически? Если вы не знаете, то не делайте этого. Просто process proc;.   -  person juanchopanza    schedule 31.03.2016


Ответы (2)


Использование malloc в C++ почти всегда является плохой идеей. В вашем случае это приводит к тому, что конструктор для struct process не вызывается, что, в свою очередь, означает, что конструктор его члена pageTable также не вызывается.

Поэтому вы вызываете push_back для неинициализированного вектора, что приводит к неопределенному поведению (и, в вашем случае, к сбою).

malloc предположительно работает только с "обычными старыми типами данных", т.е. типами, которые не нуждаются в какой-либо конструкции (имеют только конструктор по умолчанию и только простые старые типы данных в качестве членов).

Правильный способ размещения объектов в куче в C++ — использовать new, который выглядит так:

process *p = new process; // possibly add constructor arguments here

Еще лучше было бы использовать интеллектуальные указатели, такие как std::unique_ptr или, если они требуется право собственности, std::shared_ptr.

даже лучший подход — вообще не использовать указатели, особенно для объектов в вашем векторе, но, возможно, также и для вашего struct process. Используйте их только в случае необходимости!

person Daniel Jour    schedule 31.03.2016
comment
Ах хорошо. Просто чтобы убедиться, что я правильно понимаю, можно ли использовать malloc для этой структуры, если, скажем, вектора не было, и у него были только две переменные типа int? И спасибо за вашу помощь! - person user3261941; 31.03.2016
comment
@ user3261941, просто избавься от привычки использовать malloc() в программах на C++. Это нехорошо! - person SergeyA; 31.03.2016
comment
@user3261941 user3261941 Возможно, но (и это важно) просто не надо. Для этого нет абсолютно никаких причин, и это приведет к проблемам скорее раньше, чем позже. - person Daniel Jour; 31.03.2016

Неправильно malloc ваш объект process, так как malloc не будет вызывать конструктор структуры, которая вызывает конструктор std::vector<page*>.

Если возможно, сделайте свой process обычным автоматическим объектом:

process proc;

Если вам действительно нужно динамическое размещение, используйте new вместо malloc:

process* proc = new process;
person aschepler    schedule 31.03.2016