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:
Even if we “fix” it:
Your object has never been constructed, so the vector is in a garbage state. (Using the object leads to undefined behavior.)
No,
interfacemay 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: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:
Much cleaner:
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.