Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   vector::resize() and memory allocation (http://www.velocityreviews.com/forums/t284761-vector-resize-and-memory-allocation.html)

Alex Vinokur 08-02-2004 03:19 PM

vector::resize() and memory allocation
 
---------
#include <vector>
using namespace std;
struct Foo
{
Foo (int) {}
};
int main ()
{
vector<Foo> v1;
v1.resize(1);
v1[0] = Foo (100);
// Check point
return 0;
}
---------

For how many Foo instances is memory allocated at "Check point"?
It seems that for 2 insistences?
If it is truth does it mean that use of vector::resize() involves allocating extra memory?


--
Alex Vinokur
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn





Victor Bazarov 08-02-2004 03:31 PM

Re: vector::resize() and memory allocation
 
Alex Vinokur wrote:
> ---------
> #include <vector>
> using namespace std;
> struct Foo
> {
> Foo (int) {}
> };
> int main ()
> {
> vector<Foo> v1;
> v1.resize(1);
> v1[0] = Foo (100);
> // Check point
> return 0;
> }
> ---------
>
> For how many Foo instances is memory allocated at "Check point"?
> It seems that for 2 insistences?
> If it is truth does it mean that use of vector::resize() involves allocating extra memory?


The program is ill-formed because 'Foo' does not fit the requirement
"Default-constructible" needed for the call to 'resize'. It should
not compile.

Now, if you just missed that thing, and actually didn't mean to ask
a trick question (and supposedly 'Foo' actually has a default c-tor),
then it is unspecified how many objects 'v1' can actually contain
after you asked to resize it because the initial capacity of it is 0
and 'resize' _will_ cause reallocation to accommodate your object.
To what size the allocation happens is unspecified (implementation-
defined, I believe).

So, after 'Foo' is given a default c-tor, the answer to your first
question is "unknown" or "implementation-defined", the answer to your
second question is "I don't understand", and the answer to your third
question is "yes, possibly".

Victor

Alex Vinokur 08-02-2004 03:43 PM

Re: vector::resize() and memory allocation
 

"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message news:u7tPc.353$191.196@newsread1.dllstx09.us.to.ve rio.net...
> Alex Vinokur wrote:
> > ---------
> > #include <vector>
> > using namespace std;
> > struct Foo
> > {
> > Foo (int) {}
> > };
> > int main ()
> > {
> > vector<Foo> v1;
> > v1.resize(1);
> > v1[0] = Foo (100);
> > // Check point
> > return 0;
> > }
> > ---------
> >
> > For how many Foo instances is memory allocated at "Check point"?
> > It seems that for 2 insistences?
> > If it is truth does it mean that use of vector::resize() involves allocating extra memory?

>
> The program is ill-formed because 'Foo' does not fit the requirement
> "Default-constructible" needed for the call to 'resize'. It should
> not compile.
>

[snip]

To simplify the program I removed "Foo() {}" by mistake.

Here is the updated program.
---------
#include <vector>
using namespace std;
struct Foo
{
Foo () {}
Foo (int) {}
};
int main ()
{
vector<Foo> v1;
v1.resize(1);
v1[0] = Foo (100);
// Check point
return 0;
}
---------


--
Alex Vinokur
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn





Pete Becker 08-02-2004 03:46 PM

Re: vector::resize() and memory allocation
 
Victor Bazarov wrote:
>
> The program is ill-formed because 'Foo' does not fit the requirement
> "Default-constructible" needed for the call to 'resize'. It should
> not compile.
>


The compiler should issue a diagnostic. There is no requirement that it
not compile the code.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Victor Bazarov 08-02-2004 03:49 PM

Re: vector::resize() and memory allocation
 
Pete Becker wrote:
> Victor Bazarov wrote:
>
>>The program is ill-formed because 'Foo' does not fit the requirement
>>"Default-constructible" needed for the call to 'resize'. It should
>>not compile.
>>

>
>
> The compiler should issue a diagnostic. There is no requirement that it
> not compile the code.


What would the result of such compilation be? Undefined?

Andrew Koenig 08-02-2004 03:52 PM

Re: vector::resize() and memory allocation
 

"Alex Vinokur" <alexvn@big-foot.com> wrote in message
news:2n75obFtac3qU1@uni-berlin.de...

> Here is the updated program.
> ---------
> #include <vector>
> using namespace std;
> struct Foo
> {
> Foo () {}
> Foo (int) {}
> };
> int main ()
> {
> vector<Foo> v1;
> v1.resize(1);
> v1[0] = Foo (100);
> // Check point
> return 0;
> }
> ---------


At "Check point", one Foo object exists, namely v1[0].
That object was created by the call to resize, and then overwritten by
assignment from the Foo(100) object, which was then destroyed.



Alex Vinokur 08-02-2004 04:25 PM

Re: vector::resize() and memory allocation
 

"Pete Becker" <petebecker@acm.org> wrote in message news:410E61BB.2D99C886@acm.org...
> Victor Bazarov wrote:
> >
> > The program is ill-formed because 'Foo' does not fit the requirement
> > "Default-constructible" needed for the call to 'resize'. It should
> > not compile.
> >

>
> The compiler should issue a diagnostic. There is no requirement that it
> not compile the code.
>
> --
>
> Pete Becker
> Dinkumware, Ltd. (http://www.dinkumware.com)



g++ doesn't compile this code.

------ foo.cpp ------
#include <vector>
using namespace std;

struct Foo
{
Foo (int) {}
};

int main ()
{
vector<Foo> v;
v.resize(1);
v[0] = Foo (100);
return 0;
}
---------------------


------ Compilation ------

$ g++ --version
g++ (GCC) 3.3.1 (cygming special)
[---omitted---]

$ g++ foo.cpp
/usr/include/c++/3.3.1/bits/stl_vector.h: In member function `void
std::vector<_Tp, _Alloc>::resize(unsigned int) [with _Tp = Foo, _Alloc =
std::allocator<Foo>]':
foo.cpp:12: instantiated from here
/usr/include/c++/3.3.1/bits/stl_vector.h:452: error: no matching function for
call to `Foo::Foo()'
foo.cpp:5: error: candidates are: Foo::Foo(const Foo&)
foo.cpp:6: error: Foo::Foo(int)

-------------------------

--
Alex Vinokur
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn





Pete Becker 08-02-2004 04:28 PM

Re: vector::resize() and memory allocation
 
Victor Bazarov wrote:
>
> Pete Becker wrote:
> > Victor Bazarov wrote:
> >
> >>The program is ill-formed because 'Foo' does not fit the requirement
> >>"Default-constructible" needed for the call to 'resize'. It should
> >>not compile.
> >>

> >
> >
> > The compiler should issue a diagnostic. There is no requirement that it
> > not compile the code.

>
> What would the result of such compilation be? Undefined?


Up to the implementor. It has nothing to do with the standard's notion
of undefined behavior.

Let's back up a bit -- this is a common area for confusion:

The standard says that compilers that claim to conform to the standard
must compile well-formed programs, and it specifies what the behavior of
such programs is. That behavior isn't necessarily unique, because some
aspects of the language are implementation-defined (such a construct is
valid, and the implementation must document what it does -- for example,
whether char is signed or unsigned is implementation-defined, so testing
whether a char value is less than zero might always yield false) and
some are unspecified (such a construct is valid, but the implementation
is not required to document what it does -- for example, the order of
evaluation of function arguments is unspecified).

Then there are programs that are ill-formed, that is, they violate the
rules that the standard lays down for well-formed programs. For some of
these rules the behavior is simply undefined: the compiler can do
anything, and isn't required to tell you what it did or even that you
broke the rules (i=i++, for example). For most of the rules a diagnostic
is required. Having given a diagnostic, the compiler has told you that
the rules for standard C++ no longer apply; it is then free to do
anything, without violating the standard. That's the hook for conforming
extensions -- take something that's otherwise invalid and do something
meaningful with it. Microsoft's __declspec stuff, and GNU's
__attribute__ stuff, are examples of this: they occur in places where
such things aren't allowed, so the compiler is required to issue a
diagnostic; after doing this, these compilers change how they compile
the surrounding code (you don't usually see these warnings because you
run the compiler in a mode that disables them).

In the example at hand there's no obvious sensible extension behavior,
so chances are the result will actually be a refusal to compile the
code. But that's not because the standard requires it.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Pete Becker 08-02-2004 04:43 PM

Re: vector::resize() and memory allocation
 
Alex Vinokur wrote:
>
> "Pete Becker" <petebecker@acm.org> wrote in message news:410E61BB.2D99C886@acm.org...
> > Victor Bazarov wrote:
> > >
> > > The program is ill-formed because 'Foo' does not fit the requirement
> > > "Default-constructible" needed for the call to 'resize'. It should
> > > not compile.
> > >

> >
> > The compiler should issue a diagnostic. There is no requirement that it
> > not compile the code.
> >
> > --
> >
> > Pete Becker
> > Dinkumware, Ltd. (http://www.dinkumware.com)

>
> g++ doesn't compile this code.
>


I don't know of a compiler that will compile that code. Nevertheless,
the standard doesn't require that compilers not compile it. All it
requires is that they issue a diagnostic.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Alex Vinokur 08-03-2004 05:11 AM

Re: vector::resize() and memory allocation
 

"Andrew Koenig" <ark@acm.org> wrote in message news:ertPc.165649$OB3.36852@bgtnsc05-news.ops.worldnet.att.net...
>
> "Alex Vinokur" <alexvn@big-foot.com> wrote in message
> news:2n75obFtac3qU1@uni-berlin.de...
>
> > Here is the updated program.
> > ---------
> > #include <vector>
> > using namespace std;
> > struct Foo
> > {
> > Foo () {}
> > Foo (int) {}
> > };
> > int main ()
> > {
> > vector<Foo> v1;
> > v1.resize(1);
> > v1[0] = Foo (100);
> > // Check point
> > return 0;
> > }
> > ---------

>
> At "Check point", one Foo object exists, namely v1[0].
> That object was created by the call to resize, and then overwritten by
> assignment from the Foo(100) object, which was then destroyed.
>
>


You are right (See Check-point-3).

------ foo.cpp ------

#include <vector>
#include <iostream>
using namespace std;

struct Foo
{
static int ctors_s;
static int dtors_s;

Foo () { ctors_s++; cout << "Ctor()" << endl; }
Foo (const Foo&) { ctors_s++; cout << "Copy Ctor()" << endl; }
Foo (int) { ctors_s++; cout << "Ctor(int)" << endl; }
~Foo () { dtors_s++; cout << "Dtor" << endl; }
};
int Foo::ctors_s(0);
int Foo::dtors_s(0);


#define SHOW_IT(x) cout << x << " : capacity = " << v.capacity() \
<< ", vector size = " << v.size() \
<< ", alive instances = " << (Foo::ctors_s - Foo::dtors_s) \
<< endl << endl

int main ()
{
vector<Foo> v;
SHOW_IT("Check-point-1");

v.resize(1);
SHOW_IT("Check-point-2");

v[0] = Foo (100);
SHOW_IT("Check-point-3");

v.reserve(5);
SHOW_IT("Check-point-4");

return 0;
}
---------------------


------ Compilation & Run ------

$ g++ --version
g++ (GCC) 3.3.1 (cygming special)
[---omitted---]

$ g++ foo.cpp


$ a

Check-point-1 : capacity = 0, vector size = 0, alive instances = 0

Ctor()
Copy Ctor()
Dtor
Check-point-2 : capacity = 1, vector size = 1, alive instances = 1

Ctor(int)
Dtor
Check-point-3 : capacity = 1, vector size = 1, alive instances = 1

Copy Ctor()
Dtor
Check-point-4 : capacity = 5, vector size = 1, alive instances = 1

Dtor

-------------------------------


--
Alex Vinokur
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn







All times are GMT. The time now is 02:38 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.