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'.
Related
I can not understand why cout does not work in this code:
#include<iostream>
using namespace std;
int main() {
int v = 65;
int* q = &v;
char** o = (char**)&q;
cout << o << endl; // output: 012FFCAC
cout << *o << endl; // output: A
cout << **o << endl; // output: A
printf("%c",*o); // cause an error
printf("%p",*o); // works and the output=&v
And cout does not work else in this code
#include<iostream>
using namespace std;
int main() {
char v = 65;
cout << &v << endl; // output: A╠╠╠╠▀?╞«4°O
Because an int is (usually) 4 bytes 65 will fit quite neatly into just the first byte and the rest of the memory allocated for the int will be 0 this byte pattern happens to match up very closely to how strings are stored in memory.
So when the memory is accessed through a char* it will print A most of the time even though most of the prints were ill formed
int v = 65; // Byte pattern on most machines [65,0,0,0]
int* q = &v;
char** o = (char**)&q; // *o now points to [65,0,0,0] ==> ['A','\0','\0','\0'] ==> "A"
std::cout << o << std::endl;
// input: char**
// printed as: pointer
// result: 012FFCAC
std::cout << *o << std::endl; // Undefined Behaviour
// input: char*
// printed as: null terminated string
// result: "A"
std::cout << **o << std::endl; // Undefined Behaviour
// input: char
// printed as: single character
// result: 'A'
printf("%c",*o); // %c expects a [char] type but is given [pointer to char] ERROR
printf("%p",*o); // %p expects a [pointer] type and is given a [pointer to char] OK
Since a char is (usually) 1 byte there is no null terminand to stop the printing once it starts and it keeps printing whatever is around in memory until it runs into a 0 or an access violation
char v = 65;
std::cout << &v << std::endl; // &v is not a well-formed null terminated string: Undefined Behaviour
// input: char*
// printed as: null terminated string
// result: "A<whatever other data is around v in memory>"
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 have a vector of unsigned char where I copy bytes in C++. I convert all primitive types to bytes and copy to this vector of char (which is interpreted as bytes in C++). Now I am copying also strings. But I am not sure if I am converting strings to bytes. If you take a look at my output when I am printing the vector of unsigned char I am printing bytes from double int float but I am printing the real string of my variable testString. So I suppose that I am not inserting bytes of this testString on my vector of unsigned char. How should I do that?
Thanks
const std::string lat = "lat->", alt = "alt->", lon = "lon->", testString = "TEST-STRING";
double latitude = 10.123456;
double longitude = 50.123456;
double altitude = 1.123456;
std::vector<unsigned char> result(
sizeof(latitude) + sizeof(longitude) + sizeof(altitude) + testString.length());
std::cout << "copying to the vector" << std::endl;
memcpy(result.data(), &longitude, sizeof(longitude));
memcpy(result.data() + sizeof(longitude), &latitude, sizeof(latitude));
memcpy(result.data() + sizeof(longitude) + sizeof(latitude), &altitude, sizeof(altitude));
memcpy(result.data() + sizeof(longitude) + sizeof(latitude) + sizeof(altitude), testString.c_str(),
testString.length() + 1);
std::cout << "copied to the vector\n" << std::endl;
std::cout << "printing the vector" << std::endl;
for (unsigned int j = 0; j < result.size(); j++) {
std::cout << result[j];
}
std::cout << std::endl;
std::cout << "printed the vector\n" << std::endl;
// testing converting back ...................
std::cout << "printing back the original value" << std::endl;
double dLat, dLon, dAlt;
std::string value;
memcpy(&dLon, result.data(), sizeof(longitude));
memcpy(&dLat, result.data() + sizeof(longitude), sizeof(latitude));
memcpy(&dAlt, result.data() + sizeof(longitude) + sizeof(latitude), sizeof(altitude));
value.resize(testString.length());
memcpy(&value[0], result.data() + sizeof(longitude) + sizeof(latitude) + sizeof(altitude),
sizeof(value.data()) + testString.size());
std::cout << alt << dAlt;
std::cout << lat << dLat;
std::cout << lon << dLon;
std::cout << " " << value << std::endl;
std::cout << "printed back the original value\n" << std::endl;
output:
copying to the vector
copied to the vector
printing the vector
[?�gI#m���5?$#l������?TEST-STRING
printed the vector
printing back the original value
alt->1.12346lat->10.1235lon->50.1235 TEST-STRING
printed back the original value
There's no problem with your code! You're printing the actual bytes of your variables. The bytes in a double can't really be interpreted as a text string (at least, it doesn't make sense if you do) but the bytes in a text string can, producing what you see.
Let's say you've got the following code (which is really just disguised C):
#include <cstdio>
int main(int argc, char *argv[]) {
struct {
double latitude;
double longitude;
char name[30];
} structure = {
53.6344,
126.5223167,
"Keyboard Mash"
};
printf("%f %f %s\n", structure.latitude, structure.longitude, structure.name);
for (size_t i = 0; i < sizeof(structure); i += 1) {
printf("%c", ((char*)&structure)[i]);
}
printf("\n");
}
This code would (probably) print:
53.6344 126.5223167 Keyboard Mash
����������������Keyboard Mash�����������������
The first 16 bytes are from the doubles, and the next 30 are from the char[]. That's just how char[]s are stored! Your code is doing what you'd expect it to.
Of course, you can't rely on it doing this in exactly this way; that's undefined behaviour.
I feel like you were expecting something like: 128565TESTSTRING where 12, 85 and 65 are values of longitude, latitude and altitude. Well, that's not going to happen be cause you wrote 12 in the data, not "12"; therefore, it will return you the character whose ASCII code is 12. Maybe you could use something like sprintf() instead.
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.)
Why does the following code print 0? i.e. why does variable a is located right after variable d, even though pointer variable c is being declared between them?
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = &d - c;
int &f = e;
e ++;
cout << e << " " << endl;
return 0;
}
Working backwards:
e ++;
cout << e << " " << endl;
If this prints 0, then the value of e before executing this code must have been -1.
int e = &d - c;
So the result of the above address subtraction must have been -1.
unsigned int a /* = whatever, the value of a doesn't matter */;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d /* = whatever, the value of d doesn't matter */;
b is a reference to a, so &b is equivalent to &a.
So &d - c is equivalent to &d - &a, and that subtraction yields -1.
Conclusion: the address of d is sizeof (unsigned int) bytes after the address of a. (Pointer subtraction is scaled by the size of the pointed-to type.)
Probably.
In fact, the behavior of subtracting pointers to two independently defined objects is undefined. The standard says literally nothing about what it should do.
In practice, a compiler will probably generate the simplest possible code for a pointer subtraction, and that simple code will probably treat unrelated pointers as if they were comparable, even though the language doesn't say they are.
It's likely, given your program's output, that b and d happen to be allocated next to each other. Nothing says that declared variables have to be allocated in the order in which you declare them. If you want objects to be allocated in memory in a define order, put them into a struct or make them elements of an array.
It's also likely that the same program will yield different results if you run it on a different system, or on the same system with a different compiler, or on the same system with the same compiler with different compiler options. In principle, it could even behave differently with everything the same but during a different phase of the moon.
And a compiler is permitted to assume that your code's behavior is well defined, and perform transformations that are valid only given that assumption. In effect, by subtracting two unrelated pointers, you have promised the compiler that they both point to elements of the same array object or just past the end of it (where a single object is treated as a 1-element array) (or that both are null pointers; that's one difference between C and C++). You have lied to the compiler, which means it is under no further obligation to you.
Don't do that.
Unless you explicitly place objects using your own memory management system, their relative positions in memory will be compiler- and system-dependent.
your line int e = &d - c; is substracting 2 unsigned int *.
In memory, &d is 8 bytes farther then c (it depend on your system, but we suppose that an int is 4 bytes). Effectively, you construct your stack in this way :
unsigned int a = 100; // &a is 0x0
unsigned int &b = a; // &b is 0x0 (it's just an alias)
unsigned int *c = &b; // &c is 0x4
unsigned int d = (unsigned int)(c); // &d is 0x8
An unsigned int use 4 bytes in memory.
So, when your are doing &d - c, it must return 2, because your are using pointer arithmetics with unsigned int* (4*2=8);
You can try with int e = (short*)&d - (short*)c result should be 4 because short size is 2 (2*4=8).
You can try with int e = (char*)&d - (char*)c result should be 8 because char size is 1 (1*8=8).
Try to print your variables and addresses to understand :
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = (short*)&d - (short*)c;
//int &f = e;
//e ++;
cout << "&a: " << (unsigned int)&a << endl;
cout << "&b: " << (unsigned int)&b << endl;
cout << "&c: " << (unsigned int)&c << endl;
cout << "&d: " << (unsigned int)&d << endl;
cout << endl;
cout << " a: " << a << endl;
cout << " b: " << b << endl;
cout << " c: " << (unsigned int)c << endl;
cout << " d: " << d << endl;
cout << endl;
cout << " e: " << e << endl;
return 0;
}
Here, with int e = (short*)&d - (short*)c;, result is :
&a: 3220197356
&b: 3220197356
&c: 3220197360
&d: 3220197364
a: 100
b: 100
c: 3220197356
d: 3220197356
e: 4