C ++ STD Vector push_back не работает

Я делаю игру с SDL, которая использует libconfig для чтения некоторых настроек из файла. Проблема в том, что я сделал класс под названием ClipList который содержит std::vector<SDL_Rect> сохранить настройки, но при попытке добавить SDL_Rect объекты по вектору, по какой-то причине push_back ничего не делает, и я получаю пустой вектор.

Это класс:

class ClipList
{
public:
ClipList();
ClipList(int);
virtual ~ClipList();
void addClip(int,int,int,int);
void getClip(int,SDL_Rect*);
int getLength();
protected:
private:
std::vector<SDL_Rect> clips;
};
ClipList::ClipList(int l)
{
clips.reserve(l);
}

void ClipList::addClip(int x,int y,int w,int h){
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
clips.push_back(rect);
}

void ClipList::getClip(int i,SDL_Rect* rect){
rect = &(clips.at(i));
}

int ClipList::getLength(){
return clips.size();
}

И это функция, где я инициализирую объект ClipList. Эта функция вызывается из main.

void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips){
const Setting& root = placlips->getRoot();
int x,y,w,h;
try{
Setting& clipsett = root["clips"];
int cliplen = clipsett.getLength();
clips = new ClipList(cliplen);
flipclips = new ClipList(cliplen);
for(int i=0;i<cliplen;i++){
const Setting& c = clipsett[i];
if(!(c.lookupValue("x",x)&&c.lookupValue("y",y)&&c.lookupValue("w",w)&&c.lookupValue("h",h))){
continue;
}
clips->addClip(x,y,w,h);
}
}catch(const SettingNotFoundException &nfex){
cerr << "Setting not found at" << nfex.getPath() << endl;
}
}

Независимо от того, ClipList объекты инициализируются в main или же set_clips, clips.push_back(rect) не работает Емкость вектора изменяется, но никакой объект не сохраняется, поэтому я получаю segfault, если пытаюсь сделать что-то еще с вектором, даже проверяя, является ли вектор пустым или нет.

-2

Решение

Я собираюсь угадать, подпись функции

void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips);

виновник Вы выделяете память для clips а также flipclips в этой функции, но так как указатели передаются по значению, вызывающая функция не видит выделенную память.

Если вы измените сигнатуру функции на:

void set_clips(Config* placlips, ClipList*& clips, ClipList*& flipclips);

ваши проблемы должны уйти.

1

Другие решения

clips.push_back(rect) работает нормально. Ваш set_clips функция выделяет новые экземпляры ClipList, но не передает эти указатели вызывающей стороне. Вызывающий, вероятно, пытается использовать указатель мусора в качестве экземпляра инициализации, и именно поэтому вы получаете segfault.

Вам необходимо передать созданные объекты обратно. Вы должны использовать что-то вроде std :: shared_ptr<> Для этого вместо голых указателей.

Обновление о том, как сделать это без использования std :: shared_ptr<>:

Вы должны следить за собственностью и иметь дело с исключениями. С точки зрения фактической передачи, правило, которое я использую (первоначально от Lakos в «Large Scale C ++ Software Design»), заключается в том, что параметры, которые являются возвращаемыми значениями (как вы пытаетесь их использовать), являются указателями, а параметры только для чтения — значение или const-ссылка. Возвращаемые значения идут первыми.

Так что ваши set_clips функция должна выглядеть так:

void set_clips(ClipList** clips, ClipList** flip_clips, Config const& placlips)

Когда вы звоните set_clips вы передаете указатель на каждый указатель, который получит выделенное значение, и передаете const-ссылку на объект placlips, который не изменяется функцией.

Вы бы все это примерно так

ClipList* clips = 0;
ClipList* flip_clips = 0;
set_clips(&clips, &flip_flips, placlips);
// ... then do whatever comes next.

Но объединяя эти правила с std :: shared_ptr<> или повысить :: shared_ptr<> Лучше и стиль «современный C ++».

1

По вопросам рекламы [email protected]