I know there should be a delete operator with which I'm not concerned in somewhere. I just wondering, wow, it worked. Where is the argument "size" coming from?
#include<iostream>
#include<string>
class Base {
public:
Base() { }
void *operator new( unsigned int size, std::string str ) {
std::cout << "Logging an allocation of ";
std::cout << size;
std::cout << " bytes for new object '";
std::cout << str;
std::cout << "'";
std::cout << std::endl;
return malloc( size );
}
private:
int var1;
double var2;
};
int main(int argc, char** argv){
Base* b = new ("Base instance 1") Base;
}
Here is the result:
Logging an allocation of 16 bytes for new object 'Base instance 1'
It is provided by the compiler at compile time. When the compiler sees:
new ("Base instance 1") Base;
it will add a call to:
Base::operator new(sizeof(Base), "Base instance 1");
EDIT: The compiler will of course also add a call to Base::Base()
on 32 bit arch int is 4 bytes, double is 8, but the double is going to be aligned to 8 byte boundary so size = 4 + 4(empty space) + 8 = 16
Related
I want to copy a struct content in memory via char* pc the print it back but here I have an exception (reading violation)
struct af {
bool a;
uint8_t b;
uint16_t c;
};
int main() {
af t;
t.a = true;
t.b = 3;
t.c = 20;
char* pc = nullptr;
memcpy(&pc, &t, sizeof(t));
std::cout << "msg is " << pc << std::endl; // here the exception
return 0;
}
then I want to recover data from memory to another structure of same type.
I did af* tt = (af*)(pc); then tried to access to tt->a but always an exception.
You need to allocate memory before you can copy something into it. Also, pc is already the pointer, you need not take the address of it again. Moreover, the byte representation is very likely to contain non-printable characters. To see the actual effect the following copies from the buffer back to an af and prints its members (note that a cast is needed to prevent std::cout to interpret the uint8_t as a character):
#include <iostream>
#include <cstring>
struct af {
bool a;
uint8_t b;
uint16_t c;
};
int main() {
af t;
t.a = true;
t.b = 3;
t.c = 20;
char pc[sizeof(af)];
std::memcpy(pc, &t, sizeof(t)); // array pc decays to pointer to first element
for (int i=0;i<sizeof(af); ++i){
std::cout << i << " " << pc[i] << "\n";
}
af t2;
std::memcpy(&t2, pc,sizeof(t));
std::cout << t2.a << " " << static_cast<unsigned>(t2.b) << " " << t2.c;
}
Output:
0
1
2
3
1 3 20
Note that I replaced the output of pc with a loop that prints individual characters, because the binary representation might contain null terminators and pc is not a null terminated string. If you want it to be a null-terminated string, it must be of size sizeof(af) +1 and have a terminating '\0'.
I want to be able to find the size of the individual members in a struct. For example
struct A {
int a0;
char a1;
}
Now sizeof(A) is 8, but let's assume I am writing a function that will print the alignment of A as shown below where "aa" represents the padding.
data A:
0x00: 00 00 00 00
0x04: 00 aa aa aa
*-------------------------
size: 8 padding: 3
In order for me to calculate padding, I need to know the size of each individual members of a struct. So my question is how can I access to individual members of a given struct.
Also, let me know if there is another way to find the number of padding.
A simple approach would be to use sizeof operator (exploiting the fact that it does not evaluate its operand, only determines the size of the type that would result if it was evaluated) and the offsetof() macro (from <cstddef>).
For example;
#include <iostream>
#include <cstddef>
struct A
{
int a0;
char a1;
};
int main()
{
// first calculate sizes
size_t size_A = sizeof(A);
size_t size_a0 = sizeof(((A *)nullptr)->a0); // sizeof will not dereference null
size_t size_a1 = sizeof(((A *)nullptr)->a1);
// calculate positions
size_t pos_a0 = offsetof(A, a0); // will be zero, but calculate it anyway
size_t pos_a1 = offsetof(A, a1);
// now calculate padding amounts
size_t padding_a0 = pos_a1 - pos_a0 - size_a0; // padding between a0 and a1 members
size_t padding_a1 = size_A - pos_a1 - size_a1;
std::cout << "Data A:\n";
std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << pos_a0;
size_t i = pos_a0;
while (i < pos_a0 + size_a0) // print out zeros for bytes of a0 member
{
std::cout << " 00";
++i;
}
while (i < pos_a1) // print out aa for each padding byte after a_0
{
std::cout << " aa";
++i;
}
std::cout << std::endl;
std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << pos_a1;
while (i < pos_a1 + size_a1) // print out zeros for bytes of a1 member
{
std::cout << " 00";
++i;
}
while (i < size_A) // print out aa for each padding byte after a_1
{
std::cout << " aa";
++i;
}
std::cout << std::endl;
std::cout << "size: " << size_A << " padding: " << padding_a0 + padding_a1 << std::endl;
}
You can work this out if you know the content of the struct. Passing usually works like this,
Assume that your struct is this.
struct A {
int a0; // 32 bits (4 bytes)
char a1; // 8 bits (1 byte)
};
But this is not memory efficient as if you pack these structs in memory, you might get some fragmentation issues thus making the application slower. So the compiler optimizes the struct like this and the final struct to the compiler would look something like this.
struct A {
int a0;
char a1;
// padding
char __padd[3]; // 3 * 1 byte = 3 bytes.
/// Adding this padding makes it 32 bit aligned.
};
Now using this knowledge, you can see why its not easy to get the padding of an object without knowing the content of it. And paddings aren't always placed at the end of the object. For example,
struct Obj {
int a = 0;
char c = 'b';
// Padding is set here by the compiler. It may look something like this: char __padd[3];
int b = 10;
};
So how to get the padding of the struct?
You can use something called Reflection to get the content of the struct at runtime. Then workout the sizes of the data types in the struct and then you can calculate the padding by deducting the size of the previous type and the next type which gives you how the padding would look like.
As other answers have said, the offsetof macro is clearly the best solution here, but just to demonstrate that you could find the positions of your members at run time by looking at the pointers:
#include <iostream>
struct A
{
char x;
int y;
char z;
};
template <typename T>
void PrintSize ()
{
std::cout << " size = " << sizeof(T) << std::endl;
}
void PrintPosition (char * ptr_mem, char * ptr_base)
{
std::cout << " position = " << ptr_mem - ptr_base << std::endl;
}
template <typename T>
void PrintDetails (char member, T * ptr_mem, A * ptr_base)
{
std::cout << member << ":" << std::endl;
PrintSize<T>();
PrintPosition((char*) ptr_mem, (char*) ptr_base);
std::cout << std::endl;
}
int main()
{
A a;
PrintDetails('x', &a.x, &a);
PrintDetails('y', &a.y, &a);
PrintDetails('z', &a.z, &a);
}
Output on my machine:
x:
size = 1
position = 0
y:
size = 4
position = 4
z:
size = 1
position = 8
(Surprisingly, on my intel, with gcc/clang, A is of size 12! I thought that the compiler did a better job of rearranging elements)
To calculate the padding of a structure, you need to know the offset of the last member, and the size:
Concisely, if type T has a member last which is of type U, the padding size is:
sizeof(T) - (offsetof(T, last) + sizeof(U))
To calculate the total amount of padding in a structure, if that is what this question is about, I would use a GCC extension: declare the same structure twice (perhaps with the help of a macro), once without the packed attribute and once with. Then subtract their sizes.
Here is a complete, working sample:
#include <stdio.h>
#define X struct { char a; int b; char c; }
int main(void)
{
printf("%zd\n", sizeof(X) - sizeof(X __attribute__((packed))));
return 0;
}
For the above structure, it outputs 6. This corresponds to the 3 bytes of padding after a necessary for the four-byte alignment of b and at the end of the structure, necessary for the alignment of b if the structure is used as an array member.
The packed attribute defeats all padding, and so the difference between the packed and unpacked structure gives us the total amount of padding.
I want to overload the operator new[] to get the number of how many objects are to be created.
the best possible solution is to overload new[] in a way that the when creating an object using new[] would not necessitate the caller to write any extra code.
i.e using simply:
Myclass objectsArray = new Myclass[5];
example overload:
class Myclass
{
...
public:
void* operator new[](size_t size)
{
int numberOfObjects = figure out how to get number of objects to be created by this call to new[]
std::cout << "requesting: " << numberOfObjects << " objects" << std::endl;
void * temp = malloc(size) ;
return temp ;
}
...
}
the following example program:
Myclass objectsArray = new Myclass[4];
would output:
requesting: 4 objects
edit:
I want to do this just in MyClass not globaly
edit:
I'm on ‎Lubuntu 12.0 with GCC version 4.8.1
edit: Purpose of the question:
I'm using a custom memory pool allocator that can't allocate arrays out of the box. so I need to know how many objects are requested and create them one by one using a loop with the pool allocator.
You need to define a class-specific operator new. This works for me, but beware of alignment, derived classes sizes, and allocation overhead issues in the count/sizeof(MyClass) expression:
#include <iostream>
#include <memory>
#include <new>
struct MyClass {
int dummy[8];
void *operator new[](std::size_t count) {
std::cout << "allocating " << count << " bytes, " << ((count-sizeof(void*))/sizeof(MyClass)) << " items\n";
return ::operator new[](count);
}
};
int main() {
auto x = std::make_unique<MyClass[]>(10);
}
(prints: allocating 10 items) I think one can determine the exact overhead for your compiler/stdlib combination empirically by doing something like:
#include <iostream>
#include <memory>
#include <new>
struct MyClass {
char c;
char d;
virtual ~MyClass() {} // needed for introducing overhead
void *operator new[](std::size_t count) {
void *p = ::operator new[](count);
std::cout << "allocating " << count << " bytes\n";
return p;
}
};
int main() {
for( auto count : { 1, 5, 10, 20 } ) {
std::cout << "allocating " << sizeof(MyClass) << " * " << count << " items\n";
auto x = new MyClass[count];
delete[] x;
}
}
This will print, in my machine (and on Coliru):
allocating 16 * 1 items
allocating 24 bytes, 1 items
allocating 16 * 5 items
allocating 88 bytes, 5 items
allocating 16 * 10 items
allocating 168 bytes, 10 items
allocating 16 * 20 items
allocating 328 bytes, 20 items
So, our count/sizeof(MyClass) (here) should be something like
(count-sizeof(void*))/sizeof(MyClass)
But YMMV, etc.
LAST EDIT (I hope)
I had success on 64-bits linux (clang-3.4, clang-3.5 & gcc-4.8, libstdc++ & libc++) with the following how_many_elements function:
template<class T>
std::size_t how_many_elements(std::size_t bytes) {
return (bytes -
((!std::is_trivially_destructible<T>::value)*sizeof(void*))
) / sizeof(T);
}
So your operator new becomes something like:
void *operator new[](std::size_t count) {
std::cout << "allocating " << count << " bytes, " << how_many_elements<MyClass>(count) << " items\n";
return ::operator new[](count);
}
But I have not tested it in 32-bits environments and the YMMV still applies. And remember to replicate the operator new for every derived class of MyClass, obviously replacing MyClass for MyDerivedClass or whatever...
I am struggling to understand the behaviour of the program. The test.txt file is of 16 bytes where as the size of text pointed by pointer p of structure is more than 16 bytes(the string text) there are other int values too. How the extra data is stored in test file with only 16 bytes. The file is read by another structure 'b' but it gives correct values like 'a'.
int main()
{
string text("C:\\Users\\Chitra\\Desktop\\Capture.JPG");
string filepath("C:\\Users\\Chitra\\Desktop\\New folder\\Project1\\Project1\\test.txt");
fstream fout(filepath,ios::out|ios::binary);
fstream fin(filepath,ios::in|ios::binary);
struct block
{
int value;
int size;
const char* p;
int some;
};
block a;
a.value = 1457745;
a.size = text.length();
a.p = text.c_str();
a.some = 97877;
fout.write((char*)&a, sizeof(a));
fout.close();
block b;
fin.read((char*)&b, sizeof(b));
fin.seekg(0, ios::end);
cout << "file size " << fin.tellg();
fin.close();
cout << "\nsize a " << sizeof(a) << " size b " << sizeof(b);
cout << "\n"<<b.value << " " << b.size << " " << b.p << " " << b.some;
getchar();
return 0;
}
The file is only 16 bytes because when you write a.p to the file, you are writing a four-byte pointer value which points to the string in memory -- you are not writing out the string data itself.
The reason that it appears to work is that you immediately read the same pointer value back into another pointer variable in the same process, so when you read the memory pointed to by b.p, it is the same as the memory pointed to by a.p, that is, the NUL-terminated string text.
If you created a second program which just did the file read, without declaring the string text, you should expect to encounter an error or at least, not see the text.
int main()
{
string filepath("C:\\Users\\Chitra\\Desktop\\New folder\\Project1\\Project1\\test.txt");
fstream fin(filepath,ios::in|ios::binary);
struct block
{
int value;
int size;
const char* p;
int some;
};
block b;
fin.read((char*)&b, sizeof(b));
fin.seekg(0, ios::end);
cout << "file size " << fin.tellg();
fin.close();
cout << "\n size b " << sizeof(b);
cout << "\n"<<b.value << " " << b.size << " " << b.p << " " << b.some;
getchar();
return 0;
}
as Sam Mikes said block.p is pointer and you only save its value (the value of a pointer is an address of the memory it point) and because of a.p is still point to it in memory the memory do not change add delete a; like code bellow and see the different
*noted that : sizeof a and b and block is the same you can use sizeof(a) or sizeof(b) or sizeof(block) instead
#include <string>
#include<iostream>
#include <fstream>
using namespace std;
int main(){
string text("C:\\Users\\Chitra\\Desktop\\Capture.JPG");
string filepath("C:\\Users\\Chitra\\Desktop\\New folder\\Project1\\Project1\\test.txt");
fstream fout(filepath,ios::out|ios::binary);
fstream fin(filepath,ios::in|ios::binary);
struct block {
int value;
int size;
const char* p;
int some;
};
block a;
a.value =1457745;
a.size=text.length();
a.p=text.c_str();
a. some=97877;
fout.write((char*)&a,sizeof(a));
fout.close();
delete a.p;
block b;
fin.read((char*)&b,sizeof(b));
fin.seekg(0,ios::end);
cout<<"file size "<<fin.tellg();
fin.close();
cout<<"\nsize a "<<sizeof(a)<<" size b "<<sizeof(b)<<" size block "<<sizeof (block);
cout<<"\n"<<b.value<<" "<<b.size<<" "<<b.p<<" "<<b.some;
getchar();
return 0;
}
You can't just do...
fout.write(pointer, bytes);
...for any values of pointer and byte, because the data doesn't exist in contiguous memory. You must write the data embedded in the block without the pointer, and the pointed-to string data, separately. That's easiest if you move the pointer to the end of the structure, then write:
struct block
{
int value;
int some;
int size;
const char* p;
};
fout.write((char*)&a, sizeof a - sizeof a.p);
// could also "offsetof(block, p)" for size - possibly more fragile
fout.write(a.p, a.size);
Then, to read the data back:
block b;
fin.read((char*)&b, sizeof b - sizeof b.p);
b.p = new char[b.size + 1];
fin.read(b.p, b.size);
b.p[b.size + 1] = '\0'; // guarantee NUL termination
Sometime later you'll need to delete[] b.p; to deallocate the memory returned by the new[]. Alternatively, you could use another string:
block b;
fin.read((char*)&b, sizeof b - sizeof b.p);
std::string b_string(b.size, ' '); // initially b.size spaces
fin.read(&b_string[0], b.size); // overwrite with data from the file...
With the std::string, deallocation happens automatically when the destructor is invoked.
(It's actually best to use a C++ serialisation library with std::fstreams, like boost's here.)
What is data structure padding in c++ and how do i check the number of bytes padded bytes?
class a { public: int x; int y; int z; };
Processors require that certain types of data have particular alignments. For example, a processor might require that an int be on a 4-byte boundary. So, for example, an int could start at memory location 0x4000 but it could not start at 0x4001. So if you defined a class:
class a
{
public:
char c;
int i;
};
the compiler would have to insert padding between c and i so that i could start on a 4-byte boundary.
struct A
{
char c;
int i;
};
int main(int argc, char *argv[])
{
A a;
cout << "sizeof struct = " << sizeof(A) << endl;
cout << "sizeof items = " << sizeof(a.c) + sizeof(a.i) << endl;
return 0;
}
padding is done for performance reasons - see this article Data Structure Alignment for more info.
To see whether the compiler pads your data structure you could write a simple program:
#include <iostream>
class a {
public:
int x;
int y;
int z;
};
int main()
{
std::cout << sizeof(a) << std::endl; // print the total size in bytes required per class instance
a anInstance;
std::cout << &anInstance.x << std::endl; // print the address of the x member
std::cout << &anInstance.y << std::endl; // as above but for y
std::cout << &anInstance.z << std::endl; // etc
}
I added the public declaration to avoid compiler errors - It will not affect the size or padding.
Edit: Running this on my macbook air gives the following output:
12
0x7fff5fbff650
0x7fff5fbff654
0x7fff5fbff658
This shows that on my machine the total size is 12 bytes, and each member is 4 bytes apart. The ints are 4 bytes each (which can be confirmed with sizeof(int)). There is no padding.
Try this with different members in your class, for example:
class b {
public:
char w;
char x[6];
int y;
long long z;
};
Lol just create 2 identical structs, make one of them packed
e.g.
struct foo {
int a;
char b;
int c;
}
struct bar {
int a;
char b;
int c;
} __attribute__((__packed__));
sizeof(foo) - sizeof(bar)
will give you the amount of padding. Or you could also calculate manually like Duck suggested.