为什么没有对象被推送到这个向量(当它是一个结构的成员)? [英] Why aren't objects being pushed to this vector (when it's a member of a struct)?

查看:102
本文介绍了为什么没有对象被推送到这个向量(当它是一个结构的成员)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码,它通过 menuoptions 的数组循环,并在每次迭代时创建一个 ScaledRect 对象并将其推送到向量。这个向量是一个结构的成员。



我已经验证ScaledRect是用正确的值创建的,但是当我打印回 regions 向量(在第二个循环中),循环永远不会终止,值是垃圾。

  class ScaledRect:public Rect 
{
public:
ScaledRect y1,int x2,int y2);
};
ScaledRect :: ScaledRect(int x1,int y1,int x2,int y2):
_x1(x1),_y1(y1),_x2(x2),_y2(y2){}

// ScaledRect没有复制构造函数,但Rect does
Rect :: Rect(const Rect& rect)
{
x1 = rect.x1; y1 = rect.y1; x2 = rect.x2; y2 = rect.y2; BClean = KD_FALSE;
}

typedef struct
{
std :: vector< ScaledRect>区域;
} interface;

void PushRegions(interface * myself)
{
int i = 0;
while(menuoptions [i] .callback!= -1)
{
ScaledRect s =
ScaledRect(menuoptions [i] .x1,
menuoptions [i] .y1,
menuoptions [i] .x2,
menuoptions [i] .y2);
myself-> regions.push_back(s);
i ++;
}

std :: vector< ScaledRect> :: iterator iter = myself-> regions.begin();
std :: vector< ScaledRect> :: iterator done = myself-> regions.end();

while(iter!= done)
{
iter-> Dump();
iter ++;
}
}

EDIT
请注意 - 刚刚编辑 - 创建接口的内存,并且实际上将 theinterface 的地址传递到此函数。 (但是,我已经简化了这两行代码 - 实际发生的是 PushRegions 通过ptr调用一个函数,在一个新分配的内存中,一个 interface )。



我无法将所有代码都张贴在这里,

  Func pfunc = GetPFuncForInterfaceObj(); 
size_t numbytes = GetSizeForInterfaceObj();
char memory = new char [numbytes];
pfunc(memory);

pfunc c> PushRegions 和内存最终作为接口传递。

当我将 ScaledRect 对象推送到顶部声明的向量 PushRegions()起作用。

解决方案

这是完全错误的:

  size_t numbytes = GetSizeForInterfaceObj(); 
char memory = new char [numbytes];
pfunc(memory);

即使我们修复:

  size_t numbytes = GetSizeForInterfaceObj(); 
char * memory = new char [numbytes]; // note pointer
pfunc((interface *)memory); // and cast

您的对象从未构建过,因此向量处于垃圾状态。 (使用对象导致未定义的行为。)



否, interface 可能没有明确的构造函数定义,但有一个隐式构造函数,它有一个原因。它需要构建成员。您可以使用placement new(通过包含< new> )将对象放置在内存位置来构造对象:

  size_t numbytes = GetSizeForInterfaceObj(); 
char * memory = new char [numbytes]; // note pointer
pfunc(new(memory)interface); // and CREATE

现在您正在使用有效的对象。






我假设有一个很好的理由使用指针,更不用说手动构造的对象。也就是说,你的代码太多了。它既管理资源,使用一个;选择一个或另一个。



这是:

  struct interface_obj 
{
interface_obj():
mMemory(GetSizeForInterfaceObj()),
mInterface(new(& mMemory [0])interface)
{}

〜interface_obj()
{
mInterface->〜interface(); // destruct
}

interface * get()const
{
return mInterface;
}

private:
// noncopyable现在,容易添加
interface_obj(const interface_obj&);
interface_obj& operator =(const interface_obj&);

//再次,使用向量我们使用一个资源(动态缓冲区),
//不管理一个。
std :: vector< char>记忆
interface * mInterface;
};

更清洁:

  interface_obj obj; 
pfunc(obj.get());

并且它将被释放无论什么。 (你的代码不会面对例外,没有凌乱的try-catch块和其他废话。)再次,更好的是不首先有这种分配。


I have the following code, which loops through an array of menuoptions and on each iteration, creates a ScaledRect object and pushes it to a vector. This vector is a member of a struct.

I have verified that the ScaledRect is created with the correct values, yet when I print back the contents of the regions vector ( in the second loop ), the loop never terminates and the values are garbage.

class ScaledRect : public Rect
{
public:
    ScaledRect(int x1, int y1, int x2, int y2);
};
ScaledRect::ScaledRect(int x1, int y1, int x2, int y2):
    _x1(x1), _y1(y1), _x2(x2), _y2(y2){}

// ScaledRect doesn't have copy constructor, but Rect does
Rect::Rect( const Rect &rect)
{
x1=rect.x1; y1=rect.y1; x2=rect.x2; y2=rect.y2; bClean=KD_FALSE;
}

typedef struct
{
    std::vector<ScaledRect> regions;
}interface;

void PushRegions( interface * myself )
{
    int i = 0;
    while(menuoptions[i].callback != -1 )
    {
        ScaledRect s = 
          ScaledRect(menuoptions[i].x1, 
                     menuoptions[i].y1,
                     menuoptions[i].x2, 
                     menuoptions[i].y2);            
        myself->regions.push_back( s );
        i++;
    }

    std::vector<ScaledRect>::iterator iter = myself->regions.begin();
    std::vector<ScaledRect>::iterator done = myself->regions.end();

    while(iter != done)
    {
        iter->Dump();
        iter++;
    }
}

EDIT Please note - I've just edited - the memory for theinterface is created and I do actually pass in the address of theinterface to this function. (However, I have simplified those two lines here - what actually happens is that PushRegions gets called via a ptr to a function, on a piece of newly allocated memory the size of an interface ).

I can't post all of the code here - but minimally its:

Func pfunc = GetPFuncForInterfaceObj();
size_t  numbytes = GetSizeForInterfaceObj();
char memory = new char[numbytes];
pfunc(memory);

pfunc ends up being PushRegions and memory ends up being passed as an interface.

When I push the ScaledRect object to a vector declared at the top of PushRegions() it works. Has anyone got any ideas why?

解决方案

This is utterly wrong:

size_t  numbytes = GetSizeForInterfaceObj();
char memory = new char[numbytes];
pfunc(memory);

Even if we "fix" it:

size_t  numbytes = GetSizeForInterfaceObj();
char* memory = new char[numbytes]; // note pointer
pfunc((interface*)memory); // and cast

Your object has never been constructed, so the vector is in a garbage state. (Using the object leads to undefined behavior.)

No, interface may not have a constructor explicitly defined, but there is an implicit constructor, and it's there for a reason. It needs to construct the members. You can use "placement new" (by including <new>) to construct an object by placing it at a memory location:

size_t  numbytes = GetSizeForInterfaceObj();
char* memory = new char[numbytes]; // note pointer
pfunc(new (memory) interface); // and CREATE

Now you're using a valid object.


I'll assume there's a good reason for using pointers at all, let alone a manually constructed object. That said, your code does too much. It both manages a resource, and uses one; pick one or the other.

That is:

struct interface_obj
{
    interface_obj() :
    mMemory(GetSizeForInterfaceObj()),
    mInterface(new (&mMemory[0]) interface)
    {}

    ~interface_obj()
    {
        mInterface->~interface(); // destruct
    }

    interface* get() const
    {
        return mInterface;
    }

private:
    // noncopyable for now, easy to add
    interface_obj(const interface_obj&);    
    interface_obj& operator=(const interface_obj&);

    // again, with the vector we use a resource (dynamic buffer),
    // not manage one.
    std::vector<char> mMemory;
    interface* mInterface;
};

Much cleaner:

interface_obj obj;
pfunc(obj.get());

And it will be released no matter what. (Your code wouldn't in the face of exceptions, without messy try-catch blocks and other nonsense.) Again, preferable is to not have this kind of allocation in the first place.

这篇关于为什么没有对象被推送到这个向量(当它是一个结构的成员)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆