This question already has answers here:
Deserialize a byte array to a struct
(6 answers)
Serialization/Deserialization of a struct to a char* in C
(7 answers)
Serialization of struct
(5 answers)
Closed 5 years ago.
I have a vector aVector. It starts at some memory address, let it be 0x00cff87f in this case.
I also have a double D.
Now, when the program accesses the D above, it accesses some other address, of course.
What I need is that when the program accesses D above, to be pointed to address 0x00cff87f, the start of that array, and take the first sizeof(double) bytes as a double.
I tried passing pointer to D to a function and switch it, but that just changed where that pointer was pointing at, once I exited the function, D remained unchanged.
Basically, I need some way to tell the program that four bytes of memory starting at 0x00cff87f are a double and that when I ask for a double named D to get me the number at that address.
I have an array in memory that needs to be decomposed to basic types, but instead of copying everything unnecessarily, I'd rather just tell the program where it already is.
How do I do that?
EDIT:
I have a vector of unsigned chars that I want to read into other types. Something that C# BinaryReader would do with MemoryStream. I don't know how to do it in c++. There are only fstreams, there isn't one that deals with (binary) files already in memory.
double *p = (double *) &aVector;
I'm not sure why you want to do it, but it seems very likely that there is a better way to do what you're trying to do, because breaking type safety and directly accessing memory can lead to lots of weird problems.
Related
This question already has answers here:
A C program to crash the system
(5 answers)
What Can Cause a C Program to Crash Operating System
(2 answers)
What is the easiest way to make a C++ program crash?
(31 answers)
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 2 years ago.
#include <stdio.h>
#include <math.h>
int main()
{ printf("Hello World! \n");
double a = 56;
double b = pow(a,a);
double c = pow(b,b);
double d = pow(c,c);
double e = pow(d,d);
printf("%lf\n", e);
return 0;
}
when i run it, I am greeted with 'Hello World' and then 'inf'....
The aim is to create a C programme that can crash a computer bypassing OS interventions, if that is at all plausible ?
pow(a,a) already has 98 decimal digits
e goes beyond std::numeric_limits<double>::max()
I don't know where to use pow(56, 56).
In c++ we have a "boxes" with size 1, 2, 4, 8 byte(s). To solve most problems this is enough. However, sometimes required operations with large numbers. For large numbers can be used boost::multiprecision. But for some tasks this may not be enough.
But c++ doesn't care about that, because c++ cares about performance.
Do you know about cpu-cache? Look how-do-cache-lines-work.
Whenever the processor wants to fetch data from main memory, first it will look at the cache buffer to see whether the corresponding address is present in the buffer. If it is there, it will perform the operation by using the cache; no need to fetch from the main memory. This is called a "Cache hit".
If the address is not present in the cache, it is called a "Cache miss". If a cache miss has occurred, that means the processor has go to main memory to fetch the address and it takes some more time.
This question already has answers here:
No out of bounds error
(7 answers)
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 3 years ago.
Here's a sample of my code:
char chipid[13];
void initChipID(){
write_to_logs("Called initChipID");
strcpy(chipid, string2char(twelve_char_string));
write_to_logs("Chip ID: " + String(chipid));
}
Here's what I don't understand: even if I define chipid as char[2], I still get the expected result printed to the logs.
Why is that? Shouldn't the allocated memory space for chipid be overflown by the strcpy, and only the first 2 char of the string be printed?
Here's what I don't understand: even if I define chipid as char[2], I
still get the expected result printed to the logs.
Then you are (un)lucky. You are especially lucky if the undefined behavior produced by the overflow does not manifest as corruption of other data, yet also does not crash the program. The behavior is undefined, so you should not interpret whatever manifestation it takes as something you should rely upon, or that is specified by the language.
Why is that?
The language does not specify that it will happen, and it certainly doesn't specify why it does happen in your case.
In practice, the manifest ation you observe is as if the strcpy writes the full data into memory at the location starting at the beginning of your array and extending past its end, overwriting anything else your program may have stored in that space, and that the program subsequently reads it back via a corresponding overflowing read.
Shouldn't the allocated memory space for chipid be
overflown by the strcpy,
Yes.
and only the first 2 char of the string be
printed?
No, the language does not specify what happens once the program exercises UB by performing a buffer overflow (or by other means). But also no, C arrays are represented in memory simply as a flat sequence of contiguous elements, with no explicit boundary. This is why C strings need to be terminated. String functions do not see the declared size of the array containing a string's elements, they see only the element sequence.
You have it part correct: "the allocated memory space for chipid be overflowed by the strcpy" -- this is true. And this is why you get the full result (well, the result of an overflow is undefined, and could be a crash or other result).
C/C++ gives you a lot of power when it comes to memory. And with great power comes great responsibility. What you are doing gives undefined behaviour, meaning it may work. But it will definitely give problems later on when strcpy is writing to memory it is not supposed to write to.
You will find that you can get away with A LOT of things in C/C++. However, things like these will give you headaches later on when your program unexpectedly crashes, and this could be in an entire different part of your program, which makes it difficult to debug.
Anyway, if you are using C++, you should use std::string, which makes things like this a lot easier.
This question already has answers here:
Why are there different types of pointers for different data types in C?
(7 answers)
Closed 6 years ago.
First of all, I'm sorry if this question is stupid
and I'm beginner in C/C++
My question is:
Why when I want to point to a char variable like ( char x = 'A' ) I should make a pointer of char datatype? like this one ( char * pnt = &x ) ? I thought the address should be always integer of any place in Memory so the variable x in my example stored in RAM like this format (01000001) after converted (65) to the binary system in some address .. so there is an address of char type ??
I didn't understand the concept, any explanation?
That's because of strong typing in C/C++. That is one of the paradigms (python uses different one for example), but the only possible in C++. You actually can use your knowledge about pointer types and transform pointer between types. Use static_cast, dynamic_cast and so on to do this. Also if you are using C you can define a pointer to "something" - void*. This one can point to char, to int or to other type you can imagine. Notice: such transformation should be conscious. This can be a symphtom of a bad architecture or other troubles.
This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 6 years ago.
We can store string using 2 methods.
Method 1: using array
char a[]="str";
Method 2:
char *b="str";
In method 1 the memory is used only in storing the string "str" so the memory used is 4 bytes.
In method 2 the memory is used in storing the string "str" on 'Read-Only-Memory' and then in storing the pointer to the 1st character of the string.
So the memory used must be 4 bytes for storing string in ROM and then 8 bytes for storing pointer (in 64-bit machine) to the first character.
In total the 1st method uses 4 bytes and the method 2 uses 12 bytes. So is the method 1 always better than method 2 for storing strings in C/C++.
Except if you use a highly resource limited system, you should not care too much for the memory used by a pointer. Anyway, optimizing compilers could lead to same code in both cases.
You should care more about Undefined Behaviour in second case!
char a[] = "str";
correctly declares a non const character array which is initialized to "str". That means that a[0] = 'S'; is perfectly allowed and will change a to "Str".
But with
char *b = "str";
you declare a non const pointer to a litteral char array which is implicitely const. That means that b[0] = 'S'; tries to modify a litteral string and is Undefined Behaviour => it can work, segfault or anything in between including not changing the string.
All of the numbers that you cite, and the type of the memory where the string literal is stored are platform specific.
Which is more efficient way for storing strings, an array or a pointer
Some pedantry about terminology: A pointer can not store a string; it stores an address. The string is always stored in an array, and a pointer can point to it. String literals in particular are stored in an array of static storage duration.
Method 1: using array char a[]="str";
This makes a copy of the content of the string literal, into a local array of automatic storage duration.
Method 2: char *b="str";
You may not bind a non const pointer to a string literal in standard C++. This is ill-formed in that language (since C++11; prior to that the conversion was merely deprecated). Even in C (and extensions of C++) where this conversion is allowed, this is quite dangerous, since you might accidentally pass the pointer to a function that might try to modify the pointed string. Const correctness replaces accidental UB with a compile time error.
Ignoring that, this doesn't make a copy of the literal, but points to it instead.
So is the method 1 always better than method 2 for storing strings in C/C++.
Memory use is not the only metric that matters. Method 1 requires copying of the string from the literal into the automatic array. Not making copies is usually faster than making copies. This becomes more and more important with increasingly longer strings.
The major difference between method 1 and 2, are that you may modify the local array of method 1 but you may not modify string literals. If you need a modifiable buffer, then method 2 doesn't give you that - regardless of its efficiency.
Additional considerations:
Suppose your system is not a RAM-based PC computer but rather a computer with true non-volatile memory (NVM), such as a microcontroller. The string literal "str" would then in both cases get stored in NVM.
In the array case, the string literal has to be copied down from NVM in run-time, whereas in the pointer case you don't have to make a copy, you can just point straight at the string literal.
This also means that on such systems, assuming 32 bit, the array version will occupy 4 bytes of RAM for the array, while the pointer version will occupy 4 bytes of RAM for the pointer. Both cases will have to occupy 4 bytes of NVM for the string literal.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Aliasing `T*` with `char*` is allowed. Is it also allowed the other way around?
I'm using a std::array of chars to hold a value of unknown primitive type, which is no more than 10 bytes long, like so:
std::array<char, 10> val;
*reinterpret_cast<double*>(val.data()) = 6.3;
//blah blah blah...
double stuff = *reinterpret_cast<double*>(val.data());
I have read that casting back and forth through char * is not undefined, because the compiler assumes a char * may alias a value of any type. Does this still work when the value is placed in (what I assume is) an array of chars inside the object?
Note: I am aware that I could be using a union here, but that would result in a large amount of boilerplate code for what I am doing, and I would like to avoid it if necessary, hence the question.
Yes, std::array< char, 10 > does not satisfy the alignment requirements of double so that reinterpret_cast provokes UB.
Try std::aligned_storage instead.
It doesn't matter what the array is contained in.
The standard does not even consider what surrounds something (it's that basic), but does support conversion to/from char sequences.
To do this directly via reinterpret_cast and assignment, you need to have the buffer correctly aligned.
An alternative is to use memcpy, which doesn't care about alignment.
On a related issue, it's generally not a good idea to go down to the binary level. For example, a simple version change of the compiler might make a file of binary-serialized data inaccessible. A main driver for doing this anyway is raw performance considerations.