Thursday, October 15, 2015

Digest for comp.lang.c++@googlegroups.com - 11 updates in 3 topics

Victor Bazarov <v.bazarov@comcast.invalid>: Oct 14 07:53PM -0400

On 10/14/2015 6:08 PM, Stefan Ram wrote:
 
> If »Obviously sizeof is not going to work«, then
> »size of an object« might have a special meaning
> to you.
 
When object allocates dynamic memory, the term is not the "size" but
rather "footprint". std::vector<int> has the same "size" with and
without any elements if obtained using "sizeof". Yet, you can't really
deny that the footprints in RAM of vector<int>() and vector<int>(1000)
is different.
 
V
--
I do not respond to top-posted replies, please don't ask
Lynn McGuire <lmc@winsim.com>: Oct 14 07:00PM -0500

On 10/14/2015 5:10 PM, Paavo Helde wrote:
>> question so I would like to estimate file storage needed.
 
> File storage? If your object is serializable to a file why don't you just
> serialize it and look at the file size?
 
That might work. I've got a few caveats that I would have to decide about. We use string compression in our objects for one and I
would need to decide whether I want the compressed or uncompressed size.
 
Thanks,
Lynn
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 15 06:58AM

On Thu, 2015-10-15, Lynn McGuire wrote:
 
> That might work. I've got a few caveats that I would have to decide
> about. We use string compression in our objects for one and I would
> need to decide whether I want the compressed or uncompressed size.
 
Seems to me that the best thing to do, after all, could be to bite the
bullet and write a function "estimated_disk_size(const Foo&)". And to
be prepared to modify it as the class changes.
 
(I wonder if serialisation frameworks tend to have that functionality?
To not write anything but just report the size that would have been
written? I guess you could to it by serialising to some /dev/null-like
stream ...)
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Christian Gollwitzer <auriocus@gmx.de>: Oct 15 10:17AM +0200

Am 14.10.15 um 19:38 schrieb Lynn McGuire:
> This object has 100 instance variables including several vectors that
> contain vectors, etc. Is there an easy way to do this? Obviously
> sizeof is not going to work.
 
You could try a serialization framework. I know of one that is available
online..... SCNR
 
Christian
bartekltg <bartekltg@gmail.com>: Oct 15 05:52PM +0200

On 14.10.2015 23:28, Lynn McGuire wrote:
> object can be, depending on the size of the model, from 50 KB to 50 MB
> in size (swag). We are moving to multiple instances of the object in
> question so I would like to estimate file storage needed.
 
Oh, so you have some sort of serialization procedure,
it has to iterate over all members recursively.
Rewrite it to only count the size.
 
If you use streams, probably you can write you own dummy stream
that only counts bytes.
 
bartekltg
woodbrian77@gmail.com: Oct 15 09:06AM -0700

On Thursday, October 15, 2015 at 1:58:31 AM UTC-5, Jorgen Grahn wrote:
> To not write anything but just report the size that would have been
> written? I guess you could to it by serialising to some /dev/null-like
> stream ...)
 
The C++ Middleware Writer (CMW) used to have support for that
but I disabled it a few years ago. I used to pre-calculate
the "marshalling size" of messages. Then I'd marshall that size
followed by the message itself.
 
What I do now is reserve 4 bytes for the message size,
marshall the message into a buffer, and then calculate
the size of the message and place the size before the
message itself.
 
Here's an example where the message is just a message id.
 
inline void Marshal (::cmw::SendBuffer& buf
,messageid_t const& az1
,int32_t max_length=10000){
try{
buf.ReserveBytes(4);
buf.Receive(az1);
buf.FillInSize(max_length);
}catch(...){buf.Rollback();throw;}
}
 
 
There are pros and cons to both approaches. One con for
pre-calculating the size is that you have to iterate over
the message elements two times in order to marshal a message.
Another con was users of my software had to add an additional
function prototype, something like CalculateMarshallingSize,
to their classes.
 
A pro for pre-calculating is if the size of the message
exceeds your maximum for that message, you figure that out
before marshalling potentially a lot of data. I didn't find
that to be very compelling though so moved to the other
approach.
 
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
Lynn McGuire <lmc@winsim.com>: Oct 15 11:24AM -0500

On 10/15/2015 1:58 AM, Jorgen Grahn wrote:
> written? I guess you could to it by serialising to some /dev/null-like
> stream ...)
 
> /Jorgen
 
Our serialization code does report the size of the data being written to
the file.
 
Thanks,
Lynn
Lynn McGuire <lmc@winsim.com>: Oct 15 11:27AM -0500

On 10/15/2015 10:52 AM, bartekltg wrote:
 
> If you use streams, probably you can write you own dummy stream
> that only counts bytes.
 
> bartekltg
 
Yes, doesn't everyone have serialization? Our old code reports bytes
written to the file as a matter of error detection. The new code
(written in the last 20 years) does not. It would be simple to extend
though.
 
Thanks,
Lynn
Juha Nieminen <nospam@thanks.invalid>: Oct 15 11:10PM

> I would like to calculate the size of a very complex object at runtime. This object has 100 instance variables including several
> vectors that contain vectors, etc. Is there an easy way to do this? Obviously sizeof is not going to work.
 
On most unix systems you can use sbrk() (in <unistd.h>) to figure out
how much the amount of allocated heap changes. (In other words, you
first get the pointer returned by sbrk(0), then allocate a bunch of
stuff, and then get a new pointer from sbrk(0), and the difference
between these two pointers is how much the heap has increased.)
 
Of course this can be a rough estimate (because C runtimes usually
somewhat overallocate), but it will give a relatively good estimate
of the total size of the allocated data (especially if there is a lot
of it.)
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
SG <s.gesemann@gmail.com>: Oct 15 04:26AM -0700

On Wednesday, September 23, 2015 at 1:09:14 PM UTC+2, Öö Tiib wrote:
> > make a program work, but it makes programs safer.
 
> Those are "rule of five" (define all 5 or none) and "rule of zero"
> (prefer none) .
 
The "rule of five" isn't a thing. It's a little more subtle. For
example, the following class is (useless but) perfectly fine:
 
class indirect_int {
int* ptr;
public:
indirect_int(int v)
: ptr(new int(v)) {}
 
// just 2 user-defined special member functions ...
 
~indirect_int()
{ delete ptr; }
indirect_int(indirect_int && x)
: ptr(x.ptr) { x.ptr = nullptr; }
};
 
That's because a user-supplied move ctor or move assignment operator
will inhibit the creation of other compiler-generated copy or move
operations. Ideally, this inhibition would also kick in if the user
declares a dtor, copy ctor and copy assignment operator. Actually,
the 2011 rules are described this way. There is just a special
exception for C++98 compatibility. But that exception is already
*deprecated*. So, in C++11 mode (or higher) a compiler *should*
actually warn about the use of such a deprecated rule that makes the
compiler generate a copy operation that probably does the wrong thing.
So, given
 
class indirect_int {
int* ptr;
public:
indirect_int(int v)
: ptr(new int(v)) {}
 
// just 2 user-defined special member functions ...
 
~indirect_int()
{ delete ptr; }
};
 
int main() {
indirect_int a(23);
indirect_int b = a;
} // <-- double-free error here
 
I would expect a *good* compiler to issue a warning like this:
 
indirect_int b = a;
^
This makes the compiler generate a copy ctor according to
a deprecated rule. If you want indirect_int really to be
copyable consider making it explicit:
 
indirect_int(indirect_int const&) = default;
indirect_int& operator=(indirect_int const&) = default;
 
However, the more likely case is that this generated copy
ctor does the wrong thing because you declared a dtor for
indirect_int. In this case, you should add
 
indirect_int(indirect_int const&) = delete;
indirect_int& operator=(indirect_int const&) = delete;
 
to the class definition.
 
Unforunately, last time I checked, no compiler would actually issue a
warning in such a case in C++11 mode. :-( Things could be so much
simpler for beginners...
ram@zedat.fu-berlin.de (Stefan Ram): Oct 15 12:38AM

>without any elements if obtained using "sizeof". Yet, you can't really
>deny that the footprints in RAM of vector<int>() and vector<int>(1000)
>is different.
 
#include <iostream>
#include <ostream>
#include <vector>
#include <cstdlib>
 
size_t sum = 0;
 
void * operator new( ::std::size_t const siz )
{ sum += siz; return ::std::malloc( siz ); }
 
void operator delete( void * p ) noexcept
{ ::std::free( p ); }
 
void operator delete( void * p, long long unsigned int ) noexcept
{ ::std::free( p ); }
 
int main()
{ ::std::vector< void * >v;
::std::vector< void * >w;
::std::cout << sizeof v + sizeof w << '\n';
::std::cout << sum << '\n';
v.push_back( &w );
::std::cout << sum << '\n'; }
 
112
0
8
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: