Boost logo

Boost :

Subject: Re: [boost] [Interprocess] Named pipe interface proposal
From: Rob Stewart (robertstewart_at_[hidden])
Date: 2013-08-12 05:15:44


On Aug 11, 2013, at 10:32 PM, Marshall Clow <mclow.lists_at_[hidden]> wrote:

> On Aug 11, 2013, at 6:25 PM, Jason Roehm <jasonr_at_[hidden]> wrote:
>> On 08/11/2013 08:56 PM, Marshall Clow wrote:
>>>> Accessing an element of an empty vector is undefined behavior. Calling resize() to reserve space also causes elements to be initialized, which is often not needed when calling an API that indicates the number of bytes written.
>>>>
>>>> What I often do is the following:
>>>>
>>>> std::vector<char> v;
>>>> v.reserve(1024);
>>>> v.push_back(0);
>>>> read(&v[0], v.capacity());
>>>>
>>>> That can be simplified by a wrapper class.
>>> Rob --
>>>
>>> Could you have meant "resize()" instead of "reserve()" here?
>>
>> I think he meant reserve() here, for the reason indicated above the code example. Using std::vector::resize() causes any newly-added elements to be initialized, which may be a waste of effort if you're just passing that vector to a function whose job is to fill it with new data. Using reserve() instead will allocate the required memory but won't initialize it.
>
> Yes, but - it will initialize the contents of the vector by calling (the moral equivalent of) char::char() - which is a no-op - and will generate no code.

reserve() does not initialize the memory. That's the point.

>> I agree that the intent of the above code perhaps isn't readily apparent (and if you're going to use it that way, it would make sense to wrap the code to hide that implementation detail), but I can see the argument for using it. I've had some applications in the past where large (multi-GB) buffers were being allocated using std::vector instances, and in some cases, the time it took to default-initialize all of the elements was non-trivial (or even a bottleneck!)
>
> The problem with calling reserve (instead of resize) is that v.size() is still 1, and so the vector believes that it only contains a single character.
> Accessing the elements of the vector (past the first element) is technically undefined behavior.

I'm using std::vector to manage a chunk of memory. The start is given by &v[0] and the extent by v.capacity(). In C, you'd malloc() the memory and track its length in a variable. In C++, you could also use shared_array and other types, but the allocation code is explicit, you must still track the length separately, and shared_array has overhead not helpful in this use case. vector is a handy tool for the job, though this is certainly an abuse of the class since you must avoid the temptation to access more than the first element; that one element is the means to an end (or, rather, a beginning ;).

___
Rob

(Sent from my portable computation engine)


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk