Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is new-allocation needed anymore?

95 views
Skip to first unread message

JiiPee

unread,
Aug 29, 2015, 5:41:41 AM8/29/15
to
In old C++ we used "new" to create memory. But now we have all
containers, vectors and smart pointers. So was just thinking is there
any situation where we would need to use new and we can not use vector
instead? I know saving a bit memory is one reason (because a vector
takes a bit more memory than a raw c pointer). But is there any other
reason. Because on a supermachine, like mine, it does not really matter
if a vector object takes couple of bytes more than a raw pointer as I
have 16 Gig memory....

If new only used in a small machines where memory is small?

JiiPee

unread,
Aug 29, 2015, 7:40:52 AM8/29/15
to
On 29/08/2015 12:37, Stefan Ram wrote:
> JiiPee <n...@notvalid.com> writes:
>> any situation where we would need to use new and we can not use vector
> Yes. When we are implementing vector.
>

Why would you need to implement a vector? we already have std::vector....

bartekltg

unread,
Aug 29, 2015, 7:47:12 AM8/29/15
to
On 29.08.2015 11:41, JiiPee wrote:
> In old C++ we used "new" to create memory. But now we have all
> containers, vectors and smart pointers. So was just thinking is there
> any situation where we would need to use new and we can not use vector
> instead?

Some time ago i was writing small matrix library. For fun.
Compiler have hard time with vectorization it, while
vectorization of raw arrays works.
Old openMP does not work with vectors and iterators.

Both problems should be solved now. But sometimes is just
more convenient, see below. Sometimes. I too use vector often.
Beside reallocation and freeing memory (whole RAII for free)
it also make a class deep coping.

> I know saving a bit memory is one reason (because a vector
> takes a bit more memory than a raw c pointer). But is there any other
> reason. Because on a supermachine, like mine, it does not really matter
> if a vector object takes couple of bytes more than a raw pointer as I
> have 16 Gig memory....

It depends how many small object do you have.
The problem is not that you have two size_t: capacity and size*),
but that vector can hold two times the memory you need.
resevre(n) allocata 'at least n'. shrint_to_fit is only a sugestion.

On small machines you also need to keep tract of size and capacity.
The only difference is that you can use a smaller type for it.


*) if you known exactly how big data is, use array<type, N>

BTW, i have 12GB and can't run kerbal without closing a couple
tabs in chrome. Maybe RAM isn't as rich resource as we use to think;-)

There isn't such think as too much RAM. I have access to
128GB machine. "Wow, I can run bigger lattice"... and RAM disappear.

bartekltg




JiiPee

unread,
Aug 29, 2015, 8:15:53 AM8/29/15
to
On 29/08/2015 12:47, bartekltg wrote:
> On 29.08.2015 11:41, JiiPee wrote:
>> In old C++ we used "new" to create memory. But now we have all
>> containers, vectors and smart pointers. So was just thinking is there
>> any situation where we would need to use new and we can not use vector
>> instead?
>
> It depends how many small object do you have.
> The problem is not that you have two size_t: capacity and size*),
> but that vector can hold two times the memory you need.
> resevre(n) allocata 'at least n'. shrint_to_fit is only a sugestion.
>

Ok so if we need a vector which behaves differently than std::vector.
I think std::vector should have an option to set capacity = size. Then
we would not have this problem (allocating too much).
A bit strange to create my own vector class just because the std version
allocates too much memory. the capacity functionality
should be maybe optional? why is it not?

JiiPee

unread,
Aug 29, 2015, 9:24:46 AM8/29/15
to
On 29/08/2015 12:47, bartekltg wrote:
> On 29.08.2015 11:41, JiiPee wrote:
>> In old C++ we used "new" to create memory. But now we have all
>> containers, vectors and smart pointers. So was just thinking is there
>> any situation where we would need to use new and we can not use vector
>> instead?
>
> Some time ago i was writing small matrix library. For fun.
> Compiler have hard time with vectorization it, while
> vectorization of raw arrays works.
> Old openMP does not work with vectors and iterators.
>

but can't you use std::valarray for that? it does not have capacity

Öö Tiib

unread,
Aug 29, 2015, 10:37:56 AM8/29/15
to
On really small and constrained computing devices we do not use
anything dynamic (neither 'new' nor 'vector'). We have our fixed
objects and fixed arrays that perfectly occupy most of the memory
of such device. So such devices are sort of red herring.

There are still cases where 'new' may be best thing to do because of
limitations of C++ language. As an example lets take case when we
need to have covariance of pointers to new objects. Covariance
quite often helps us to get rid of pointless and ugly downcasts so
it is neat feature.

Typical case of new object needed is polymorphic 'clone' with
covariant return. It has to return raw pointer (because of covariance)
to new object (because of clone) therefore we have to use manual
resource management here with 'new' (or with 'malloc' or with some
'alloCator.allocate') for to reserve the storage that such new object
occupies.

Bo Persson

unread,
Aug 29, 2015, 12:43:58 PM8/29/15
to
Because of the underlying system.

It might be impossible (or extremely inefficient) to allow capacity==1
or capacity==127. The current wording *allows* a vector to use 8 or 16
bytes as the minimum allocation.

If you do shrink_to_fit when size==127, you might really want the
vector<double> to keep 1024 bytes rather than fragment the heap with a
1016 byte block. That's why shrink_to_fit is a (strong) recommendation,
but not binding.


Bo Persson

Jens Thoms Toerring

unread,
Aug 30, 2015, 7:29:43 AM8/30/15
to
JiiPee <n...@notvalid.com> wrote:
> In old C++ we used "new" to create memory. But now we have all
> containers, vectors and smart pointers. So was just thinking is there
> any situation where we would need to use new and we can not use vector
> instead?

Short answer: what would you have a smart pointer hold but
a pointer to allocated memory (typically allocated with
'new')?

Dynamic arrays isn't the only place 'new' would be needed
(but they can indeed be avoided by using a vector, but then
the vector class itself will need to allocated memory as has
been pointed out). Actually, your question could be seen as
part of a bigger one: do we need pointers at all anymore
(except for interfacing with legacy code)?

One example where you definitely need pointers: you want to
store a set of class instances, all derived fromt he same
base class, in a vector - e.g. all animals on a farm, so
you have an 'Animal' base class and derived 'Cow' and 'Pig'
classes. You might be tempted to use something like

std::vector< Animal > v;
v.push_back( Cow( ) );
v.push_back( Pig( ) );

But when you then call a method of the elements of the
vector, i.e.

v.back( ).foo( );

the 'Animal' base class method will be invoked, not the
method of the derived 'Pig' class! And you wouldn't even
be able to create a vector of 'Animal' instances if 'Animal'
contains pure virtual methods and thus can't be instantiated.

But if you do instead

std::vector< std::unique_ptr< Animal > > v;
v.push_back< std::unique_ptr< Animal >( new Cow ) );
v.push_back< std::unique_ptr< Animal >( new Pig ) );

then

v.back( )->foo( );

will nicely invoke the method from 'Pig' overriding the
one from 'Animal'.

That's one example where pointers are required - and when
you have pointers you typically also want to be able to
make them point to dynamically allocated objects (unless
maybe if you know in advance exactly how many are going
to be used). And for that you definitely want 'new' (or
some other form or allocation).

Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

JiiPee

unread,
Aug 30, 2015, 9:07:13 AM8/30/15
to
On 30/08/2015 12:29, Jens Thoms Toerring wrote:
> JiiPee <n...@notvalid.com> wrote:
>> In old C++ we used "new" to create memory. But now we have all
>> containers, vectors and smart pointers. So was just thinking is there
>> any situation where we would need to use new and we can not use vector
>> instead?
> But if you do instead
>
> std::vector< std::unique_ptr< Animal > > v;
> v.push_back< std::unique_ptr< Animal >( new Cow ) );
> v.push_back< std::unique_ptr< Animal >( new Pig ) );
>
> then
>
> v.back( )->foo( );
>
> will nicely invoke the method from 'Pig' overriding the
> one from 'Animal'.

I was more like talking about the pair new-delete
so doing the memory management using them alone. In which situation that
would be good?


JiiPee

unread,
Aug 30, 2015, 9:08:11 AM8/30/15
to
On 30/08/2015 13:53, Stefan Ram wrote:
> j...@toerring.de (Jens Thoms Toerring) writes:
>> Short answer: what would you have a smart pointer hold but
>> a pointer to allocated memory (typically allocated with
>> 'new')?
> A pointer to allocated memory, typically allocated with
> a make function.
>
> auto object = ::std::make_unique< A >( args );

yes, this looks good/better. Although I dont think you need that ::std::
... just std::


bartekltg

unread,
Aug 30, 2015, 9:58:50 AM8/30/15
to
It looks like my server doesn't update this newsgroup anymore.


On 29.08.2015 14:15, JiiPee wrote:
> On 29/08/2015 12:47, bartekltg wrote:
>> On 29.08.2015 11:41, JiiPee wrote:
>>> In old C++ we used "new" to create memory. But now we have all
>>> containers, vectors and smart pointers. So was just thinking is there
>>> any situation where we would need to use new and we can not use vector
>>> instead?
>>
>> It depends how many small object do you have.
>> The problem is not that you have two size_t: capacity and size*),
>> but that vector can hold two times the memory you need.
>> resevre(n) allocata 'at least n'. shrint_to_fit is only a sugestion.
>>
>
> Ok so if we need a vector which behaves differently than std::vector.
> I think std::vector should have an option to set capacity = size.

And we have since c++11. It is shrink_to_fit I was talking about.
but i may not work:
"
void shrink_to_fit();
14 Remarks: shrink_to_fit is a non-binding request to reduce capacity()
to size(). [ Note: The
request is non-binding to allow latitude for implementation-specific
optimizations. — end note ]
"

> Then
> we would not have this problem (allocating too much).
> A bit strange to create my own vector class just because the std version
> allocates too much memory. the capacity functionality
> should be maybe optional? why is it not?

Because vectro should be ready for multiple 'push_back'.
If you always keep only enough memory,
vector <double> tab;
for (int i=0;i<N;++)
tab.pushback(sin(0.1*i));
will be quadratic.

A standard solution for that is to allocate "too much" memory.
Then it is linear.


vector is a very good universal container. But sometimes
a feature, needed 99% of times, is not optimal for you.

> but can't you use std::valarray for that? it does not have capacity

I can. It even may be better for compiler to optimize the code.



bartekltg


bartekltg

unread,
Aug 30, 2015, 10:09:01 AM8/30/15
to
On 30.08.2015 13:29, Jens Thoms Toerring wrote:
> JiiPee <n...@notvalid.com> wrote:
>> In old C++ we used "new" to create memory. But now we have all
>> containers, vectors and smart pointers. So was just thinking is there
>> any situation where we would need to use new and we can not use vector
>> instead?
>
> Short answer: what would you have a smart pointer hold but
> a pointer to allocated memory (typically allocated with
> 'new')?

A pointer to any object I don't want to keep as static variable.
For example, like you have said, for polymorphism.

The array of object is exactly the one place where you
should use a container (vector), not a chunk of manually
allocated memory.

> Dynamic arrays isn't the only place 'new' would be needed
> (but they can indeed be avoided by using a vector, but then
> the vector class itself will need to allocated memory as has
> been pointed out).

I understand that OP ask about 'a normal user' should
use news, not someone who write standard library.
In other words, where we should take allocation in our hands
instead of using containers.


> Actually, your question could be seen as
> part of a bigger one: do we need pointers at all anymore
> (except for interfacing with legacy code)?

I think it is very different question.
Of course the answer is still the same: yes, we need new/delete;
yes, we need pointers, both smart and raw.

bartekltg

JiiPee

unread,
Aug 30, 2015, 10:34:49 AM8/30/15
to
On 30/08/2015 15:08, bartekltg wrote:
> On 30.08.2015 13:29, Jens Thoms Toerring wrote:
>> JiiPee <n...@notvalid.com> wrote:
>>> In old C++ we used "new" to create memory. But now we have all
>>> containers, vectors and smart pointers. So was just thinking is there
>>> any situation where we would need to use new and we can not use vector
>>> instead?
>> ointed out).
>
> I understand that OP ask about 'a normal user' should
> use news, not someone who write standard library.
> In other words, where we should take allocation in our hands
> instead of using containers.

yes, and using possible delete as well (or if smar pointers, then
reset). so total management

JiiPee

unread,
Aug 30, 2015, 11:12:50 AM8/30/15
to
On 30/08/2015 15:55, Stefan Ram wrote:
> bartekltg <bar...@gmail.com> writes:
>> I understand that OP ask about 'a normal user' should
>> use news, not someone who write standard library.
> When Stroustrup teaches C++, he shows us how to implement
> a Vector class early (at about 4% of the book) in his book
> »The C++ programming language«.
>

but I think he adds many times, that dont do this at home but use rather
std versions..

bartekltg

unread,
Aug 30, 2015, 11:37:31 AM8/30/15
to
On 30.08.2015 16:55, Stefan Ram wrote:
> bartekltg <bar...@gmail.com> writes:
>> I understand that OP ask about 'a normal user' should
>> use news, not someone who write standard library.
>
> When Stroustrup teaches C++, he shows us how to implement
> a Vector class early (at about 4% of the book) in his book
> »The C++ programming language«.

The idea behind STL is that you do not have to write you own vector.
I can write ma own container, sorting algorithm, matrix library,
graphic library(probably;))... but in most cases I should not.

I will try rephrase the question one more time:

Someone is building a class. The class have a set
of data. We can do it by including std::vector<whatever>
as a member (and this is a preferable solution for most
cases) or by manually allocating (freeing, keeping eye on
usage and reallocating) memory.
And OP is asking, when he should go with second option
and do more work.

One example is when we do not need a frequent small resizing,
and want to keep additional memory usage low.
I'm sure this is not the only one.



bartekltg





bartekltg

unread,
Aug 30, 2015, 11:57:44 AM8/30/15
to
On 30.08.2015 17:37, bartekltg wrote:

> One example is when we do not need a frequent small resizing,
> and want to keep additional memory usage low.

OK, it is not that bad, at least in gcc.

int main()
{
const int N = 1025;
vector<int> A(N,0), B,C,D;
B.resize(N);
D.reserve(N);
cout<<A.capacity()<<" "<<B.capacity()<<" "<<C.capacity()<<"
"<<D.capacity()<<endl;

for (int i=0;i<N;i++)
{
A[i]=i;
B[i]=i;
C.push_back(i);
D.push_back(i);
}

cout<<A.capacity()<<" "<<B.capacity()<<" "<<C.capacity()<<"
"<<D.capacity()<<endl;

A.push_back(0);

cout<<A.capacity()<<endl;


return 0;
}

output:

1025 1025 0 1025
1025 1025 2048 1025
2050

Constructing, resizing ad reserving do not grab additional
memory.


bartekltg

Jens Thoms Toerring

unread,
Aug 30, 2015, 4:22:17 PM8/30/15
to
Note: if you've a smart pointer you mat not have to do a
reset() on it - if it goes out of scope (in the case of
unique_ptr) - or the last instance holding a pointer to the
memory (for shared_ptr) - the memory is deallocated automa-
tically - the reset() is part of the smart pointers destruc-
tion.

Now, about the usefulness of new/delete: I think it depends
a bit on what you're doing. Some of the stuff I do is inter-
facing external devices used in physics and chemistry labs,
and there you often have to fetch lots of data (think, for
example, a trace from an oscilloscope which, with modern
devices, can consist of hundreds of MBs of data). Now, at
a low level you must use system functions like read() that
expect a buffer the data get read into. Of course, you could
create a local buffer large enough, read the data into it
and then copy them all over to a vector. But that would at
least double the memory used (at least temporarily) and
would use up some extra time. And what you then typically
do with the data doesn't require any of the bells and
whistles a vector comes with - often it is nothing more
exciting than writing them to a file. So it's simply
more efficient not to use an extra array but an allocated
buffer that one deletes once the data are safely on the
disk.

It would be different if one would be able to write directly
to the vectors memory area and change it's size afterwards,
but that's not allowed.

So I'd say that vectors tend to be the best choice when
you have something that often grows and shrinks but when
all you need is some temporary (but not local to a single
function or method) buffer which doesn't change in size
an allocated array will do as well and, in a number of
situations, even better.

An alternative in such situations might seem to be a std::array,
but there's the problem that you know the required size only
in the method that "talks" to the device (which will tell you
how many data it's got for you). And this makes it, as far
as I can see, impossible to get it (the array) out of this
method since the size is an essential part of the std::array
you've got to specify it in either the return value type or
for an argument of the method. Also template "magic" won't
help since the size isn't something known at compile time.
But perhaps someone else here has a clever solution for
this...

Paavo Helde

unread,
Aug 30, 2015, 5:36:24 PM8/30/15
to
j...@toerring.de (Jens Thoms Toerring) wrote in
news:d4h6v4...@mid.uni-berlin.de:
> Now, at
> a low level you must use system functions like read() that
> expect a buffer the data get read into. [...]
> It would be different if one would be able to write directly
> to the vectors memory area and change it's size afterwards,
> but that's not allowed.

What do you mean? What's wrong with using a properly resized std::vector or
std::string buffer for reading a file handle?

Jens Thoms Toerring

unread,
Aug 30, 2015, 6:29:04 PM8/30/15
to
Chances are I'm missing something, but the only way to get
at the underlying pointer to the vector's (or string's) data
is the data() method (and for strings there-s also c_str())
- and that just returns a const pointer, i.e. something I
can't pass to read(). Ok, one can use '&vec[0]' to obtain
that address also, but I hadn't considered to use that
address for writing to the arrays or strings memory as some-
thing kosher - but if it is why does data() return a const
pointer only? Could be that I'm too squeamish and it's above
the board to do it that way. If it is it would make some
things quite a bit simpler;-)

Öö Tiib

unread,
Aug 30, 2015, 6:58:51 PM8/30/15
to
I do not know why we need 'delete'. I haven't had 'delete' for more
than decade in my own code. There are too large variety of well-tested
stock smart pointers available.

I 'reset' smart pointer for same reasons why I 'clear' a container.
It has to be empty by program logic and so I 'reset' or 'clear' it.
I may need 'new' for some rare reasons like for covariance.

Jens Thoms Toerring

unread,
Aug 30, 2015, 7:25:57 PM8/30/15
to
Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> j...@toerring.de (Jens Thoms Toerring) writes:
> >at the underlying pointer to the vector's (or string's) data
> >is the data() method (and for strings there-s also c_str())
> >- and that just returns a const pointer, i.e. something I

> (You must mean a »pointer to const«, not a »const pointer«.)

> There are two entries in ::std::vector.

> value_type* data() noexcept; and
> const value_type* data() const noexcept;

> . If the ::std::vector object is const-qualified, the call
> returns a pointer to const value_type. Otherwise, it returns
> a pointer to value_type.

> (Disclaimer: I have not tried this, just read it from docs.)

Thanks! Took another look and found that the data() method for
vectors does indeed has a pointer to non-const version, while
strings don't (and you usually use character arrays as "byte"
arrays when using read() and friends). So I had overlooked that
with a vector more is allowed than with strings and assumed that
if strings don't do it also vectors won't (and then it seemed to
be a bit like taking too many liberties with the innards of a
vector). I'll have to see how I can use this newly acquired piece
of knowledge;-)

JiiPee

unread,
Aug 30, 2015, 7:59:27 PM8/30/15
to
On 31/08/2015 00:25, Jens Thoms Toerring wrote:
> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>> j...@toerring.de (Jens Thoms Toerring) writes:
>>> at the underlying pointer to the vector's (or string's) data
>>> is the data() method (and for strings there-s also c_str())
>>> - and that just returns a const pointer, i.e. something I
> Thanks! Took another look and found that the data() method for
> vectors does indeed has a pointer to non-const version, while
> strings don't (and you usually use character arrays as "byte"
> arrays when using read() and friends). So I had overlooked that
> with a vector more is allowed than with strings and assumed that
> if strings don't do it also vectors won't (and then it seemed to
> be a bit like taking too many liberties with the innards of a
> vector). I'll have to see how I can use this newly acquired piece
> of knowledge;-)
> Regards, Jens
"

It would be different if one would be able to write directly
to the vectors memory area and change it's size afterwards,
but that's not allowed.

"

But dont you still have the problem that the vector will allocate
possible two times more memory than you need because of the capacity?
yes you can write to its memory I think, but you cannot really manage
yourself the amount of memory the vector allocates, can you?


bartekltg

unread,
Aug 30, 2015, 8:21:19 PM8/30/15
to
On 31.08.2015 01:59, JiiPee wrote:
> On 31/08/2015 00:25, Jens Thoms Toerring wrote:
>> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>>> j...@toerring.de (Jens Thoms Toerring) writes:
>>>> at the underlying pointer to the vector's (or string's) data
>>>> is the data() method (and for strings there-s also c_str())
>>>> - and that just returns a const pointer, i.e. something I
>> Thanks! Took another look and found that the data() method for
>> vectors does indeed has a pointer to non-const version, while
>> strings don't (and you usually use character arrays as "byte"
>> arrays when using read() and friends). So I had overlooked that
>> with a vector more is allowed than with strings and assumed that
>> if strings don't do it also vectors won't (and then it seemed to
>> be a bit like taking too many liberties with the innards of a
>> vector). I'll have to see how I can use this newly acquired piece
>> of knowledge;-)
>> Regards, Jens
> "
>
> It would be different if one would be able to write directly
> to the vectors memory area and change it's size afterwards,
> but that's not allowed.
>
> "
>
> But dont you still have the problem that the vector will allocate
> possible two times more memory than you need because of the capacity?

I have checked it and it is not that bad.
If you insert data by series of 'push_back()' it may be
two times too much. But if you resize to necessary size,
or reserve enough space, vector use only so much memory
(plus allocator data + alignment Bo Persson was talking,
about). At least in a simple test in gcc 4.9.2.

bartekltg






JiiPee

unread,
Aug 30, 2015, 9:04:22 PM8/30/15
to
oh, did not consider that. So without pushbacks it should allocate about
the requested memory. But obviously one would like be sure that this is
how the vector always works. The resize documentation does not mention
anything about it really.

Paavo Helde

unread,
Aug 31, 2015, 12:25:33 AM8/31/15
to
JiiPee <n...@notvalid.com> wrote in news:8KNEx.227975$GG3....@fx10.am4:
Oh come on guys, the compiler/STL writers are worried about the performance
at least as much as you are (plus they actually know what they are doing).
They will not go and preallocate reams of extra memory just because of fun
or something.

Cheers
Paavo

Paavo Helde

unread,
Aug 31, 2015, 12:55:10 AM8/31/15
to
j...@toerring.de (Jens Thoms Toerring) wrote in
news:d4hed0...@mid.uni-berlin.de:
Since C++11 std::vector has non-const data() overload and std::string has
the contiguous buffer guarantee. So both vector::data() and &str[0] are
kosher now. In practice, &vec[0] and &str[0] have always been kosher
(albeit a bit ugly and non-intuitive - I guess that's why non-const
vector::data() was added).

Cheers
Paavo

woodb...@gmail.com

unread,
Aug 31, 2015, 1:39:09 AM8/31/15
to
On Sunday, August 30, 2015 at 5:58:51 PM UTC-5, Öö Tiib wrote:
>
> I do not know why we need 'delete'. I haven't had 'delete' for more
> than decade in my own code. There are too large variety of well-tested
> stock smart pointers available.
>
> I 'reset' smart pointer for same reasons why I 'clear' a container.
> It has to be empty by program logic and so I 'reset' or 'clear' it.
> I may need 'new' for some rare reasons like for covariance.

This line

auto request=::std::make_unique<cmw_request>(localbuf);

results in a text segment that's 71 bytes bigger than this line

auto request=::std::unique_ptr<cmw_request>(new cmw_request(localbuf));

using gcc 5.1.1 on Linux. I've taken that line from this
program - http://webEbenezer.net/misc/cmwAmbassador.cc

I compile the code with std=c++1y for the version with
make_unique. For the other version I compile it with
std=c++11. If I compile the version with new using
std=c++1y, it's 88 bytes bigger than the version with
make_unique. The version that uses new is attractive
because it's small and doesn't require a C++2014 compiler.


Brian
Ebenezer Enterprises - In G-d we trust.
http://breitbart.com

Öö Tiib

unread,
Aug 31, 2015, 4:34:03 AM8/31/15
to
You write that binary generated from stutter is longer with
std=c++1y compiler ... yet you choose stutter? Odd choice.
Maybe I misunderstand something but it seems like you are
making it both less readable and less efficient?
As for std=c++11 how you know that the difference with
std=c++1y is anyhow related to that 'request' variable?

In general if there is actually some quality of implementation
issue and it matters and fix reduces readability (like stutter
in your example) then I expect a comment in code that
documents the reason, (but I can't see one in your example).

My strong push towards readability is because I work with
teams on code that has to stay maintainable years later.
Other people may of course do whatever they want with
their code.

bartekltg

unread,
Aug 31, 2015, 8:10:16 AM8/31/15
to
On 29.08.2015 14:15, JiiPee wrote:
> On 29/08/2015 12:47, bartekltg wrote:
>> On 29.08.2015 11:41, JiiPee wrote:
>>> In old C++ we used "new" to create memory. But now we have all
>>> containers, vectors and smart pointers. So was just thinking is there
>>> any situation where we would need to use new and we can not use vector
>>> instead?
>>
>> It depends how many small object do you have.
>> The problem is not that you have two size_t: capacity and size*),
>> but that vector can hold two times the memory you need.
>> resevre(n) allocata 'at least n'. shrint_to_fit is only a sugestion.
>>
>
> Ok so if we need a vector which behaves differently than std::vector.
> I think std::vector should have an option to set capacity = size.

And we have since c++11. It is shrink_to_fit I was talking about.
but i may not work:
"
void shrink_to_fit();
14 Remarks: shrink_to_fit is a non-binding request to reduce capacity()
to size(). [ Note: The
request is non-binding to allow latitude for implementation-specific
optimizations. — end note ]
"

> Then
> we would not have this problem (allocating too much).
> A bit strange to create my own vector class just because the std version
> allocates too much memory. the capacity functionality
> should be maybe optional? why is it not?

bartekltg

unread,
Aug 31, 2015, 8:10:16 AM8/31/15
to

bartekltg

unread,
Aug 31, 2015, 8:10:18 AM8/31/15
to
Somebody see this post? This is a third try.
Because vector should be ready for multiple 'push_back'.

Chris Vine

unread,
Aug 31, 2015, 8:13:20 AM8/31/15
to
On Mon, 31 Aug 2015 02:04:05 +0100
JiiPee <n...@notvalid.com> wrote:
[snip]
> oh, did not consider that. So without pushbacks it should allocate
> about the requested memory. But obviously one would like be sure that
> this is how the vector always works. The resize documentation does
> not mention anything about it really.

std::vector::reserve() must allocate as much as requested (or throw)
and can allocate more, but in practice it will do what you ask it
subject to the requirements of alignment. A reasonable implementation
is not going to do something stupid gratuitously.

Of course, in the case that your most recent posts have been concerned
with - using std::vector as a buffer for some other function such as
read() to read into - you should really use std::vector::resize()
rather than std::vector::reserve() so that the vector is correctly
sized (std::vector::data() returns "a pointer such that [data(), data()
+ size()) is a valid range"), but that has the disadvantage that it
acts like calloc(), namely that for built-in types it default-inserts
elements into its memory with value initialization to 0.

If avoiding any unnecessary zeroing operations on built-in types when
constructing the buffer is wanted, then if all you want is a buffer
where the size is not known at compile time but is known at run time
(or you want the buffer to have a longer lifetime than block scope) it
is perfectly fine to use std::unique_ptr with the new[] expression; and
if you know the size of the buffer at compile time, you should use a
C-style array or std::array where all you want is a plain buffer with
block scope.

On your more general question "is new-allocation needed anymore", it is
also needed for placement new.

Chris

woodb...@gmail.com

unread,
Aug 31, 2015, 3:03:59 PM8/31/15
to
On Monday, August 31, 2015 at 3:34:03 AM UTC-5, Öö Tiib wrote:
> On Monday, 31 August 2015 08:39:09 UTC+3, woodb...@gmail.com wrote:
> >
> > This line
> >
> > auto request=::std::make_unique<cmw_request>(localbuf);
> >
> > results in a text segment that's 71 bytes bigger than this line
> >
> > auto request=::std::unique_ptr<cmw_request>(new cmw_request(localbuf));
> >
> > using gcc 5.1.1 on Linux. I've taken that line from this
> > program - http://webEbenezer.net/misc/cmwAmbassador.cc
> >
> > I compile the code with std=c++1y for the version with
> > make_unique. For the other version I compile it with
> > std=c++11. If I compile the version with new using
> > std=c++1y, it's 88 bytes bigger than the version with
> > make_unique. The version that uses new is attractive
> > because it's small and doesn't require a C++2014 compiler.
>
> You write that binary generated from stutter is longer with
> std=c++1y compiler ... yet you choose stutter? Odd choice.

I choose it in part to avoid requiring a C++ 2014 compiler.

> Maybe I misunderstand something but it seems like you are
> making it both less readable and less efficient?

I admit the make_unique form is easier to read. I would
like to see support for make_unique added to C++ 2011
compilers.

Brian
Ebenezer Enterprises - G-d is love.
http://webEbenezer.net

Jens Thoms Toerring

unread,
Aug 31, 2015, 3:46:23 PM8/31/15
to
Yup, I think I had been looking at the option of using a vector
while still using C++98 and decided that it wouldn't be viable
(I tend to be a bit paranoid and avoid anything not guaranteed
by the standard - I don't want someone ending up with wrong
data because I used some fishy shortcuts). And then I didn't
check again if anything had changed about that with C++11, just
remembering that there was some kind of a snag.

Of course, there's the point that Chris Vines brings up, i.e.,
that resize() on the vector will initialize all of that data
without that being necessary. On the other had when you have
to get several MBs from a device that's typically the real
bottleneck (at least if it arrives via USB or LAN or some-
thing even slower) compared the initialization of the memory
with 0.

Nice to know that I've now got one more option;-)

Thanks and best regards, Jens

Richard

unread,
Aug 31, 2015, 3:51:26 PM8/31/15
to
[Please do not mail me a copy of your followup]

Paavo Helde <myfir...@osa.pri.ee> spake the secret code
<XnsA50750867D195m...@216.166.105.131> thusly:

>Since C++11 std::vector has non-const data() overload and std::string has
>the contiguous buffer guarantee.

Be aware that writing through the pointer returned by data() is
undefined behavior.
<http://en.cppreference.com/w/cpp/string/basic_string/data>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Paavo Helde

unread,
Aug 31, 2015, 4:30:10 PM8/31/15
to
legaliz...@mail.xmission.com (Richard) wrote in
news:ms2b7j$opa$1...@news.xmission.com:

> [Please do not mail me a copy of your followup]
>
> Paavo Helde <myfir...@osa.pri.ee> spake the secret code
> <XnsA50750867D195m...@216.166.105.131> thusly:
>
>>Since C++11 std::vector has non-const data() overload and std::string
>>has the contiguous buffer guarantee.
>
> Be aware that writing through the pointer returned by data() is
> undefined behavior.
> <http://en.cppreference.com/w/cpp/string/basic_string/data>

I think nobody here has proposed to use basic_string::data() (and casting
away const) for obtaining a pointer to a mutable buffer, we were talking
about vector::data().

But otherwise, yes it would be nice to have also a non-const version of
basic_string::data() for write access. Meanwhile I recalled another issue
with &string[0] apart of ugliness, namely it is UB when the length of the
string is zero (whereas vector::data() on a zero size vector is OK).

Cheers
Paavo

Chris M. Thomasson

unread,
Aug 31, 2015, 4:32:55 PM8/31/15
to
> "Paavo Helde" wrote in message
> news:XnsA507EF07353Cmy...@216.166.105.131...
[...]

> I think nobody here has proposed to use basic_string::data() (and casting
> away const) for obtaining a pointer to a mutable buffer, we were talking
> about vector::data().

Is casting the const away Kosher?

Paavo Helde

unread,
Aug 31, 2015, 4:35:13 PM8/31/15
to
"Chris M. Thomasson" <nos...@nospam.nospam> wrote in
news:ms2dl3$v64$1...@speranza.aioe.org:
No, it is not. Why do you ask?

Chris Vine

unread,
Aug 31, 2015, 4:41:18 PM8/31/15
to
std::vector::data() is not const for a non-const vector.

Jens Thoms Toerring

unread,
Aug 31, 2015, 4:58:42 PM8/31/15
to
Richard <legaliz...@mail.xmission.com> wrote:
> Paavo Helde <myfir...@osa.pri.ee> spake the secret code
> <XnsA50750867D195m...@216.166.105.131> thusly:

> >Since C++11 std::vector has non-const data() overload and std::string has
> >the contiguous buffer guarantee.

> Be aware that writing through the pointer returned by data() is
> undefined behavior.
> <http://en.cppreference.com/w/cpp/string/basic_string/data>

There-in lies a certain problem: it's not uncommon that the
devices I have to interface return ASCII data for certain re-
quests (e.g., with an ascilloscope, the current timebase or
sensitivity of a channel) and binary for requests that return
lots of data (e.g. a measured waveform). And what I really got
to like about C++'s strings is that they, in contrast to C
strings, can perfectly handle binary data. So, in the best of
all worlds, I would prefer to simply use a string for every-
thing (and leave the interpretation of what they contain to
some later stage) - but, unfortunately, because of the UB you
mention, they can't be used as buffers the same way as vectors.
Of course, I could use a vector<char>, it's just that that then
has to be converted to a string in all the cases where the de-
vice did send an ASCII string. Well, life's never perfect;-)

Best regards, Jens

Paavo Helde

unread,
Aug 31, 2015, 5:08:50 PM8/31/15
to
j...@toerring.de (Jens Thoms Toerring) wrote in
news:d4jtfj...@mid.uni-berlin.de:

> So, in the best of
> all worlds, I would prefer to simply use a string for every-
> thing (and leave the interpretation of what they contain to
> some later stage) - but, unfortunately, because of the UB you
> mention, they can't be used as buffers the same way as vectors.

Yes they can - by using slightly uglier syntax &string[0] (or (string.empty
()? NULL: &string[0]) instead of string.data().

Chris M. Thomasson

unread,
Aug 31, 2015, 6:03:40 PM8/31/15
to
> "Paavo Helde" wrote in message
> news:XnsA507EFE42D700m...@216.166.105.131...
Ummm, I totally misread the message Pavvo!

Sorry about that non-sense.

;^/

Öö Tiib

unread,
Aug 31, 2015, 6:31:41 PM8/31/15
to
On Monday, 31 August 2015 22:03:59 UTC+3, woodb...@gmail.com wrote:
> On Monday, August 31, 2015 at 3:34:03 AM UTC-5, Öö Tiib wrote:
> > On Monday, 31 August 2015 08:39:09 UTC+3, woodb...@gmail.com wrote:
> > >
> > > This line
> > >
> > > auto request=::std::make_unique<cmw_request>(localbuf);
> > >
> > > results in a text segment that's 71 bytes bigger than this line
> > >
> > > auto request=::std::unique_ptr<cmw_request>(new cmw_request(localbuf));
> > >
> > > using gcc 5.1.1 on Linux. I've taken that line from this
> > > program - http://webEbenezer.net/misc/cmwAmbassador.cc
> > >
> > > I compile the code with std=c++1y for the version with
> > > make_unique. For the other version I compile it with
> > > std=c++11. If I compile the version with new using
> > > std=c++1y, it's 88 bytes bigger than the version with
> > > make_unique. The version that uses new is attractive
> > > because it's small and doesn't require a C++2014 compiler.
> >
> > You write that binary generated from stutter is longer with
> > std=c++1y compiler ... yet you choose stutter? Odd choice.
>
> I choose it in part to avoid requiring a C++ 2014 compiler.

That is good reason all alone if you have to support older
compilers.

>
> > Maybe I misunderstand something but it seems like you are
> > making it both less readable and less efficient?
>
> I admit the make_unique form is easier to read. I would
> like to see support for make_unique added to C++ 2011
> compilers.

The compiler makers may do it or not, it is their choice. C++11
itself won't change since we don't have time machines.

Jens Thoms Toerring

unread,
Aug 31, 2015, 7:42:08 PM8/31/15
to
I'll take your word for it;-)

Thank you and best regards, Jens

Paavo Helde

unread,
Sep 1, 2015, 1:33:03 AM9/1/15
to
j...@toerring.de (Jens Thoms Toerring) wrote in
news:d4k722...@mid.uni-berlin.de:

> Paavo Helde <myfir...@osa.pri.ee> wrote:
>> j...@toerring.de (Jens Thoms Toerring) wrote in
>> news:d4jtfj...@mid.uni-berlin.de:
>> > So, in the best of
>> > all worlds, I would prefer to simply use a string for every-
>> > thing (and leave the interpretation of what they contain to
>> > some later stage) - but, unfortunately, because of the UB you
>> > mention, they can't be used as buffers the same way as vectors.
>
>> Yes they can - by using slightly uglier syntax &string[0] (or
>> (string.empty ()? NULL: &string[0]) instead of string.data().
>
> I'll take your word for it;-)
>

Thank you, but there is no need to take my word ;-) These are the
relevant quotes from the standard:

21.4.1 basic_string general requirements

5. The char-like objects in a basic_string object shall be stored
contiguously. That is, for any basic_string object s, the identity
&*(s.begin() + n) == &*s.begin() + n
shall hold for all values of n such that 0<= n < s.size().

21.4.5 basic_string element access

const_reference operator[](size_type pos) const;
reference operator[](size_type pos);

2. Returns: *(begin() + pos) if pos < size().

Cheers
Paavo


0 new messages