简体   繁体   English

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

[英]C++ STD Vector push_back doesn't seem to work

I'm making a game with SDL that used libconfig to read some settings from a file.我正在使用 SDL 制作一个游戏,该游戏使用 libconfig 从文件中读取一些设置。 The problem is that I made a class called ClipList that contains a std::vector<SDL_Rect> to store the settings but when trying to add SDL_Rect objects to the vector, for some reason push_back does nothing and I end up with an empty vector.问题是我创建了一个名为ClipList的类,它包含一个std::vector<SDL_Rect>来存储设置,但是当尝试将SDL_Rect对象添加到向量时,由于某种原因 push_back 什么也不做,我最终得到一个空向量。

This is the class:这是课程:

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();
}

And this is the function where I initialize the ClipList object.这是我初始化 ClipList 对象的函数。 This function gets called from main.这个函数是从 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;
    }
}

Regardless of whether the ClipList objects get initialized in main or set_clips , clips.push_back(rect) doesn't work.无论ClipList对象是在main还是set_clips初始化, clips.push_back(rect)都不起作用。 The capacity of the vector changes but no object gets stored so I end up with a segfault if I try to do anything else with the vector, even checking if the vector is empty or not.向量的容量会发生变化,但不会存储任何对象,因此如果我尝试对向量执行任何其他操作,即使检查向量是否为空,最终也会出现段错误。

I am going to guess, the signature of the function我猜,函数的签名

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

is the culprit.是罪魁祸首。 You are allocating memory for clips and flipclips in this function but since the pointers are passed by value, the calling function does not see the allocated memory.您正在此函数中为clipsflipclips clips分配内存,但由于指针是按值传递的,因此调用函数看不到分配的内存。

If you change the function signature to:如果将函数签名更改为:

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

your problems should go away.你的问题应该消失。

clips.push_back(rect) is working fine. clips.push_back(rect)工作正常。 Your set_clips function allocates new ClipList instances but does not pass those pointers back to the caller.您的set_clips函数会分配新的 ClipList 实例,但不会将这些指针传回给调用者。 The caller is probably attempting to use a garbage pointer as an initialise instance and that is why you are getting a segfault.调用者可能试图使用垃圾指针作为初始化实例,这就是为什么您会遇到段错误。

You need to pass the created objects back.您需要将创建的对象传回。 You should use something like std::shared_ptr<> to do that instead of bare pointers.您应该使用 std::shared_ptr<> 之类的东西来代替裸指针。

Update on how to do this without using std::shared_ptr<>:关于如何在不使用 std::shared_ptr<> 的情况下执行此操作的更新:

You need to keep track of ownership and deal with exceptions.您需要跟踪所有权并处理异常。 In terms of the actual passing, the rule I use (originally from Lakos in "Large Scale C++ Software Design") is that parameters that are return values (as you are attempting to use them) are pointers, and read-only parameters are by value or const-reference.就实际传递而言,我使用的规则(最初来自“大型 C++ 软件设计”中的 Lakos)是作为返回值的参数(当您尝试使用它们时)是指针,而只读参数是由值或常量引用。 Return values come first.返回值是第一位的。

So, your set_clips function should look like this:因此,您的set_clips函数应如下所示:

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

When you call set_clips you pass a pointer to each pointer that will receive the allocated value, and pass a const-reference to the placlips object that is not modified by the function.当您调用set_clips您将一个指针传递给每个将接收分配的值的指针,并将一个常量引用传递给未被函数修改的 placlips 对象。

You would all it something like this:你会像这样:

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

But combining those rules with std::shared_ptr<> or boost::shared_ptr<> is better and the "modern C++" style.但是将这些规则与 std::shared_ptr<> 或 boost::shared_ptr<> 结合起来会更好,并且是“现代 C++”风格。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM