Object tries to eat potatoeses

Started by
27 comments, last by SiCrane 10 years, 6 months ago

I don't think it's good to use malloc with objects in c++. If you want to pre-allocate a fixed chunk of memory, consider using new[] POD objects.

Advertisement

 



You cannot allocate memory with "new[]" without creating the objects and calling their constructors unless "placement new" is used.

It sounds to me more like you don't understand the difference between placement new and ::operator new. You're use of the phrase "calling the constructor" and the way you distinguish between object creation, memory allocation, and the constructors and the way you originally didn't understand about copy constructors would lead me to think that getting a good grasp on basic object life cycle should come before using crufty corners of the language to reimplement what the standard library does on the basis of premature microoptimization.

Sure, it's fun but it's ultimately unproductive and generally leads to the false belief that C++ is error-prone and hard to use.

Stephen M. Webb
Professional Free Software Developer


 

I don't think it's good to use malloc with objects in c++. If you want to pre-allocate a fixed chunk of memory, consider using new[] POD objects.

You cannot allocate memory with "new[]" without creating the objects and calling their constructors unless "placement new" is used. Unless you mean some "new char[]" which doesn't sound like it's much better in regards to alignment I have no idea what would that use.

What I mean is making your objects POD. That way your objects won't have any constructors or destructors to call; new[] will only allocate memory. I think that's a good way to go if you must pre-allocate memory.

I could use the '#pragma pack(1)' (I think it's MSVC specific though) to ensure no padding is fit but that would make the whole programming experience within that program to be a layer much closer to assembly (because I would need to control/check/test every single variable) wouldn't it ?

No... Don't do that.
#pragma pack(1)
struct 
{
 char a; short b; int c;
} data;
data.c = data.b = data.a = 42;
printf( "%d", data.c );
What kind of assembly would you use to implement that? Would you use bit-shifting and masking operations? Unaligned load and stores? Do you have to load multiple loads into a few registers, then shift, mask and OR them together to reconstruct the variable that straddles two different aligned-words?

The compiler puts in padding for a good reason -- it makes the generated assembly code much simpler.

Isn't both 8B and 16B alignments "heart stabbing" when you might have only one or a few occurrences of those 8B/16B and lots of say, 2B or 1B in a struct (Are classes the same ?) ? I believe the same applies to simple variables even ?

I don't get the "heart stabbing" phrase; is it a Lithuanian saying?
The compiler will insert the minimum amount of padding to ensure that each variable is correctly aligned.
Yes, classes and structs are the same thing.
//     \/ alignment requirement for the struct itself
struct a1 { char a,b,c,d; } //no padding
struct a4 { int a,b,c; } // no padding
struct a8 { double a,b,c,d; } //no padding
struct a8 { double a; int b,c; }//no padding
struct a8 { double a; int b; char _pad_[4]; }//first member requires 8B alignment, round up structure size to a multiple of 8
struct a4 { int a; short b; char c; char _pad_; }//first member requires 4B alignment, round up structure size to a multiple of 4
struct a4 { short a; char _pad_[2]; int b; }//second member requires 4B alignment, insert 2 padding bytes before it so that it is aligned
struct a2 { char a; char _pad_; short b; }//second member requires 2B alignment, insert 1 padding byte before it so that it is aligned
It's a good rule of thumb to declare your struct members form largest to smallest, to minimize padding:
struct {
  double a, b, c;
  int d, e;
  short f;
  char g;
  char _pad_;//the struct requires 8B alignment, pad size up to a multiple of 8
}//1 byte total padding

struct {
  int d;
  char _pad0_[4];//next member requires 8B alignment, pad up to that size
  double a, b;
  short f;
  char _pad1_[2];//next member requires 4B alignment, pad up to that size
  int d, e;
  char g;
  char _pad2_[7];//next member requires 8B alignment, pad up to that size
  double c;
}//13 bytes of padding total!

the class object would be 16 Bytes, say, having 3 ints and 4 chars ? Would it just be fine with an 8Byte alignment because it will read data members one by one and will pad 4 zero Bytes to each int as well as 7 zero Bytes to chars ?

struct { int a,b,c; char d,e,f,g; };
The int members require 4B alignment and the chars require 1B alignment. The class alignment is max(4,1), or 4B. 8B will also work, because it's a multiple of 4. There will be no padding, because as long as the class itself is 4B aligned, then all the members will be aligned.

The second example uses the vector which is overhead for something which should be simple.
low-details that affect performance, I actually need to pre-allocate memory for dynamic object creation with manually creating each object there, so I need only memory nothing more.

With all the debugging features disabled, and when used correctly, the overhead of a std::vector is about 8 bytes of space, and zero performance (when compared to the same operations performed manually). What's even better, is that their use of manual construction/destruction is fully tested and debugged.
Regarding performance, you should generally go with the easy to read/write/maintain solution first, and then complicate it with an optimized version if it is demonstrated to be necessary.

The overhead of iterating over your array checking an embedded active flag (as in your other thread) is likely going to be a much bigger performance pitfall.
If you make a post about the actual problem you're trying to solve (a pool allocator?), you'll get some good solutions, rather than just a schooling on alignment and exotic new flavours wink.png

 

If your program has a bottleneck that you can prove is related to padding, you probably have enough data to seriously consider a structure-of-arrays approach, rather than the usual array-of-structures.

That said, this thread is wandering off topic, and the discussion is getting rather advanced given this thread is in For Beginners.


 

This topic is closed to new replies.

Advertisement