C ++ STD Vector push_back似乎不起作用

时间:2014-04-13 03:41:59

标签: c++ vector sdl libconfig

我正在使用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;
    }
}

无论ClipListmainset_clips对象是否已初始化,clips.push_back(rect)都无效。向量的容量发生了变化,但是没有对象被存储,所以如果我尝试用向量做任何其他事情,甚至检查向量是否为空,我最终会得到段错误。

2 个答案:

答案 0 :(得分:1)

我猜,函数的签名

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

是罪魁祸首。您正在为此函数分配clipsflipclips的内存,但由于指针是按值传递的,因此调用函数不会看到已分配的内存。

如果您将功能签名更改为:

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

你的问题应该消失。

答案 1 :(得分:1)

clips.push_back(rect)工作正常。您的set_clips函数会分配新的ClipList实例,但不会将这些指针传递回调用者。调用者可能正在尝试使用垃圾指针作为初始化实例,这就是您遇到段错误的原因。

您需要将创建的对象传回。你应该使用像std :: shared_ptr&lt;&gt;这样的东西。这样做而不是裸指针。

在不使用std :: shared_ptr&lt;&gt;:

的情况下更新如何执行此操作

您需要跟踪所有权并处理异常。就实际传递而言,我使用的规则(最初来自Lakos&#34;大规模C ++软件设计&#34;)是返回值的参数(当你试图使用它们时)是指针,并且读取-only参数是按值或const-reference。返回值是第一位的。

因此,您的set_clips函数应如下所示:

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

当你调用set_clips时,你传递一个指向每个将接收分配值的指针的指针,并将const-reference传递给未被该函数修改的placlips对象。

你会这样:

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

但是将这些规则与std :: shared_ptr&lt;&gt;结合使用或者boost :: shared_ptr&lt;&gt;更好,现代的C ++&#34;风格。

相关问题