question about vectors

B

bahoo

Hi,

In the main function, I have

vector<vector<Store>> stores;
vector<Store> v(11);
stores.push_back(v);

and here is the Store class:

class Store
{
public:
Store();
IplImage* img;
};

Store::Store()
{
img = cvCreateImage(cvSize(512,512), IPL_DEPTH_32F, 1);
}

The strange thing is that all the 11 "v" have the same "img", with the
same address in the memory. What I wanted is of course 11 "v" with
different "img".

Can anyone spot the error?
Thanks
bahoo
 
K

Kira Yamato

Hi,

In the main function, I have

vector<vector<Store>> stores;
vector<Store> v(11);
stores.push_back(v);

and here is the Store class:

class Store
{
public:
Store();
IplImage* img;
};

Store::Store()
{
img = cvCreateImage(cvSize(512,512), IPL_DEPTH_32F, 1);
}

The strange thing is that all the 11 "v" have the same "img", with the
same address in the memory. What I wanted is of course 11 "v" with
different "img".

Can anyone spot the error?
Thanks
bahoo

I just found this out myself. It turns out that the way std::vector
initializes its array is this:
1) create a default object,
2) use the copy constructor to create all the elements of the array.

In your case, it created one copy of the default Store object. Then
the copy constructor simply made 11 copies each copying from the same
img pointer value.

So maybe you should do this instead:

vector<Store> v;
for(int i = 0; i < 11; i++) v.push_back(Store());
 
S

Saeed Amrollahi

Hi,

In the main function, I have

vector<vector<Store>> stores;
As you may be know, you should put an space between > and > like this:
vector<vector<Store> > stores;
of course, in next version of standard C++, there is no need for the
space.
vector<Store> v(11);
stores.push_back(v);

and here is the Store class:

class Store
{
public:
        Store();
        IplImage* img;

};

Store::Store()
{
        img = cvCreateImage(cvSize(512,512), IPL_DEPTH_32F, 1);

}

The strange thing is that all the 11 "v" have the same "img", with the
same address in the memory. What I wanted is of course 11 "v" with
different "img".

Can anyone spot the error?
I think, it is natural. According to Standard C++ document and
Stroustrup's 3rd, if you construct a vector with just size argument,
the default constructor of the template argument class called size
times.
If you want different images, you should define another constructor
for Store class and after creating object, use vector's push_back
function. In this case, because you have a pointer inside Store class,
you should define copy constructor, destructor and assignment
operator.
Thanks
bahoo

Regards,
S. Amrollahi
 
S

Salt_Peter

As you may be know, you should put an space between > and > like this:
vector<vector<Store> > stores;
of course, in next version of standard C++, there is no need for the
space.





I think, it is natural. According to Standard C++ document and
Stroustrup's 3rd, if you construct a vector with just size argument,
the default constructor of the template argument class called size
times.

This is incorrect. If that were true, then the OP wouldn't have the
issue he has.
A unique image would have been allocated for each element.
The default ctor is invoked once and a copy of it is used to
initialize all the elements.
Hence the problem.
If you want different images, you should define another constructor
for Store class and after creating object, use vector's push_back
function. In this case, because you have a pointer inside Store class,
you should define copy constructor, destructor and assignment
operator.

Why? the default copy ctor and the default assignment operator copy
that pointer by value.
He needs a destructor, yes, to call cvReleaseImage(&img) or whatever
deallocates the image in that implementation.
 
S

Saeed Amrollahi

This is incorrect. If that were true, then the OP wouldn't have the
issue he has.
A unique image would have been allocated for each element.
The default ctor is invoked once and a copy of it is used to
initialize all the elements.
Hence the problem.


Why? the default copy ctor and the default assignment operator copy
that pointer by value.
He needs a destructor, yes, to call cvReleaseImage(&img) or whatever
deallocates the image in that implementation.




- Show quoted text -- Hide quoted text -

- Show quoted text -

Hi

Thank you very much. I accept your comments about copying pointer by
value semantic. I wanted to offer a general solution for designing
class. I want to obey the Rule of Big Three.

Regards,
S. Amrollahi
 
D

Daniel T.

Hi,

In the main function, I have

vector<vector<Store>> stores;
vector<Store> v(11);
stores.push_back(v);

and here is the Store class:

class Store
{
public:
        Store();
        IplImage* img;

};

Store::Store()
{
        img = cvCreateImage(cvSize(512,512), IPL_DEPTH_32F, 1);

}

The strange thing is that all the 11 "v" have the same "img", with the
same address in the memory. What I wanted is of course 11 "v" with
different "img".

Can anyone spot the error?

The error is that you don't have a correct copy constructor and
assignment op in your class. The vector uses the defaults wich don't
do what you want. I expect that your Store class had a destructor
(though you didn't post the code here.) Anytime a class needs a custom
destructor, it is very likely it needs a custom assignment operator
and copy constructor as well.

The proper solution is to write a copy constructor for your class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,181
Messages
2,570,970
Members
47,537
Latest member
BellCorone

Latest Threads

Top