c++ strings and pointers confusion - c++

string * sptemp = (string *) 0x000353E0;
What does this code exactly want to say ?
I know that in the left side we define a string pointer but I couldn't understand the right part.

It means take a numeric value, convert it to a pointer with that value as the address it points to, and then use that value to initialise the variable sptemp.
If the memory at that address contains a valid string object, then you can use the pointer to access it. If not, trying to do so will give undefined behaviour.

string * sptemp = (string *) 0x000353E0;
What does this code exactly want to say ?
It says, treat the data located at address 0x000353E0 as though it holds a string and assign the address to the variable sptemp. The data can be accessed through the pointer variable sptemp after that.

These comments are mostly right, but not completely. We don't actually know that string is std::string here. It could be that string is a bit of memory-mapped hardware whose address on the OP's embedded SBC is defined by the hardware 0x000353E0. In that case, this is completely sensible, and what people do all the time. The pointer "string *sptemp" is set to point to the hardware interface.
But it's probably nonsense.

Related

Accessing memory mapped register

Assume there is a memory mapped device at address 0x1ffff670. The device register has only 8-bits. I need to get the value in that register and increment by one and write back.
Following is my approach to do that,
In the memory I think this is how the scenario looks like.
void increment_reg(){
int c;//to save the address read from memory
char *control_register_ptr= (char*) 0x1ffff670;//memory mapped address. using char because it is 8 bits
c=(int) *control_register_ptr;// reading the register and save that to c as an integer
c++;//increment by one
*control_register_ptr=c;//write the new bit pattern to the control register
}
Is this approach correct? Many thanks.
Your approach is almost correct. The only missing part - as pointed out in the comments on the question - is adding a volatile to the pointer type like so:
volatile unsigned char * control_register_ptr = ...
I would also make it unsigned char, since that is usually a better fit, but that's basically not that much different (the only meaningful difference would be when shifting the value down.)
The volatile keyword signals to the compiler the fact that the value at that address might change from outside the program (i.e. by code that the compiler doesn't see and know about.) This will make the compiler more conservative in optimizing loads and stores away, for example.

C++ - Casting variables and how does it treat them?

I've been pretty curious about this for awhile now maybe I am 100% wrong, but when you cast one type to another does it look at the memory/value and then treat that memory/value as the new type?
For example:
char Letter = 'A';
int iLetter = static_cast<int>(Letter);
//iLetter is 65
If this is correct does it look at the memory location / value of "Letter" and then change the value to represent what ever you are casting it to? I came to this theory by picturing all values as integers and then being casted to the char/struct/class etc.
Hopefully this is a full question, I'd just like a good understanding of how casting really works with the values / information to change them into new values, etc.
In situations when you cast a value (as opposed to a pointer or a reference) the compiler constructs a new value from the one being cast, as opposed to interpreting an existing location as the new type.
Specifically, the code looks at the value of Letter, which is a char, and constructs an iLetter from it by extending the char to an int using the integer conversion rules of C++. This may include sign extension for signed types, so a negative signed char will become a negative int.
On the other hand, when you cast a pointer, the same location is interpreted as a new type.
In your case, static_cast create temp variable with new type and then set it in iLetter.
Edit:
It means static_cast doesn't change the main var type and just read it. at the end, it doesn't directly put the converted value inside iLetter. it will create temp var with new type and that will be set inside iLetter.
What your cast is doing is an implicit conversion, and that means the cast is redundant and not needed, just do this:
int iLetter = Letter; //This is a safe conversion as well
If this is correct does it look at the memory location / value of "Letter"
Yes. Obviously, the value of Letter is looked at, as in the value of the variable seen, otherwise the compiler would have no idea what you are talking about.
- and then change the value to represent whatever you are casting it to?
The original value is not changed, only copied, and that value is casted to the int, to return the character code.

Get the value of a variable using the hexadecimal memory address

I just want to get the value using the hex address:
#include<stdio.h>
int main()
{
int *hold, value=10;
hold = &value;
printf("%p",hold);
}
It gives me the address 0x7fffd7c24334. I just want to know that if there is a way in C or C++ so that I can get directly the value of "value" using hex number 0x7fffd7c24334 for the time being. I suppose the address of the variable hold is the same for sometime so that 0x7fffd7c24334 still point to value, but I am not sure.
Assuming that this address is consistent upon every execution of your program, you can use this:
int value2 = *(int*)0x7fffd7c24334;
But please note that this assumption is generally wrong!
The address of a local variable in a function depends on the state of the stack (the value of the SP register) at the point in execution when the function is called.
It might possibly work in main, since this function is called only once, and the SP register should have the same value upon every execution of your program. But even if it does work, that address will change as soon as you add variables before value. To put it in simple words, don't use this method.
printf("%d",*hold);
De-reference and use %d.
You cannot rely on the hex address.
See here: http://ideone.com/RdY4Ni
I think you can use this:
printf("%x", hold);

C++: Changing value of Pointer Strings

There is something that has been bugging me for a while and I need an anwer for it,
char *p = "hello world";
p="wazzup";
p="Hey";
Here I declare an pointer to point to a string (or in other words I made a string by using a pointer)
I have had some strange results with this that i normally wouldnt have gotten if I used an char array string
cout <<p<< endl; //"Hey" Gets printer
cout <<p+8<< endl; // I kept adding numbers till "wazzup" got printed
cout <<p+29<< endl; // No matter how much I increment, I cant print "Hello World"
So my question is:
When I change the value that a char pointer is pointing to. Does it
overwrite the original Data like it would do with char array;
or it creates a new string right before it in the memory and points to it;
or does it add the new string at the begining of the old one(including null);
or does it create a new string in a new place in the memory and I was able to print "wazzup" only by chance
It does none of the options above. Changing the value of a pointer merely changes to the address in memory it points to. In each case of the assignments to p, it is set to point to the first character of a (different) string literal - which is stored in memory.
The behaviour of using a pointer that points beyond the end a string literal such as
cout <<p+8<< endl
is undefined. This is why using pointers is fraught with danger.
The behaviour you are seeing is implementation dependant: The compiler stores the strings literals adjacent in memory, so running off the end of one runs into another. Your program might equally have crashed when compiled with a different compiler.
By adding to the pointer, you are increasing the address value... so while printing it will print the value stored at that memory location and nothing else...
If you could print
"hello world"
"wazzup"
that will be a fluke :)
All three of these are string literal constants. They appear directly in your executable's binary, and each time you assign p, you point to these locations in memory. They are completely separate memory; reassigning p to another one does not modify any string data.
You are only making the pointer point to something else each time you assign to it. So there is no scope for data being overwritten anywhere. What happens under the hood is implementation dependent, so what you see is just by pure chance. When you do this:
cout <<p+8<< endl;
you are going beyond the bounds of the string literal, invoking undefined behaviour.
When I change the value that a char pointer is pointing to. Does it
-overwrite the original Data like it would do with char array.
No, the data part of your address space contains all the three strings "Hello World", "wazzup", and "Hey". When you change the pointer, you are just changing the value in p to the starting address of either of above strings. Changing the address a pointer is pointing to and changing the value a pointer is pointing to are two different things.
-or it creates a new string right before it in the memory and points to it.
The compiler creates the strings(character bytes) at the compile time and NOT at run-time.
-or does it create a new string in a new place in the memory and I was able to print "wazzup" only by chance
I think above answer covers this question.
-or does it add the new string at the begining of the old one.(including null)
It depends on the compiler specification.
The three strings are not located in same memory position. This three memory may be sequential or different location.If compiler allocation three memory then you find it using +/- some value. It totally depends on compiler. In c you can ready any memory location so you never get any error while +/- then pointer p.
Since they 3 are not same strings, they are located at different parts of memory. I think they could be separated by 64 byte aligning. try p+64 :)
Only same strings sit in the same location of memory and only if compiler supports it.
There is a probability "wazzup" at p+64 and "hey" at p+128(if you use VC++ 2010 express and you have pentium-m cpu and you use windows xp sp-3)
cout <<*(p+64)<< endl;
cout <<*(p+128)<< endl;

What are the use pointer variables?

I've recently tried to really come to grips with references and pointers in C++, and I'm getting a little bit confused. I understand the * and & operators which can respectively get the value at an address and get the address of a value, however why can't these simply be used with basic types like ints?
I don't understand why you can't, for example, do something like the following and not use any weird pointer variable creation:
string x = "Hello";
int y = &x; //Set 'y' to the memory address of 'x'
cout << *y; //Output the value at the address 'y' (which is the memory address of 'x')
The code above should, theoretically in my mind, output the value of 'x'. 'y' contains the memory address of 'x', and hence '*y' should be 'x'. If this works (which incidentally on trying to compile it, it doesn't -- it tells me it can't convert from a string to an int, which doesn't make much sense since you'd think a memory address could be stored in an int fine).
Why do we need to use special pointer variable declarations (e.g. string *y = &x)?
And inside this, if we take the * operator in the pointer declaration literally in the example in the line above, we are setting the value of 'y' to the memory address of 'x', but then later when we want to access the value at the memory address ('&x') we can use the same '*y' which we previously set to the memory address.
C and C++ resolve type information at compile-time, not runtime. Even runtime polymorphism relies on the compiler constructing a table of function pointers with offsets fixed at compile time.
For that reason, the only way the program can know that cout << *y; is printing a string is because y is strongly typed as a pointer-to-string (std::string*). The program cannot, from the address alone, determine that the object stored at address y is a std::string. (Even C++ RTTI does not allow this, you need enough type information to identify a polymorphic base class.)
In short, C is a typed language. You cannot store arbitrary things in variables.
Check the type safety article at wikipedia. C/C++ prevents problematic operations and functional calls at compliation time by checking the type of the operands and function parameters (but note that with explicit casts you can change the type of an expression).
It doesn't make sense to store a string in an integer -> The same way it doesn't make sense to store a pointer in it.
Simply put, a memory address has a type, which is pointer. Pointers are not ints, so you can't store a pointer in an int variable. If you're curious why ints and pointers are not fungible, it's because the size of each is implementation defined (with certain restrictions) and there is no guarantee that they will be the same size.
For instance, as #Damien_The_Unbeliever pointed out pointers on a 64-bit system must be 64-bits long, but it is perfectly legal for an int to be 32-bits, as long as it is no longer than a long and nor shorter than a short.
As to why each data type has it's own pointer type, that's because each type (especially user-defined types) is structured differently in memory. If we were to dereference typeless (or void) pointers, there would be no information indicating how that data should be interpreted. If, on the other hand, you were to create a universal pointer and do away with the "inconvenience" of specifying types, each entity in memory would probably have to be stored along-side its type information. While this is doable, it's far from efficient, and efficiency is on of C++'s design goals.
Some very low-level languages... like machine language... operate exactly as you describe. A number is a number, and it's up to the programmer to hold it in their heads what it represents. Generally speaking, the hope of higher level languages is to keep you from the concerns and potential for error that comes from that style of development.
You can actually disregard C++'s type-safety, at your peril. For instance, the gcc on a 32-bit machine I have will print "Hello" when I run this:
string x = "Hello";
int y = reinterpret_cast<int>(&x);
cout << *reinterpret_cast<string*>(y) << endl;
But as pretty much every other answerer has pointed out, there's no guarantee it would work on another computer. If I try this on a 64-bit machine, I get:
error: cast from ‘std::string*’ to ‘int’ loses precision
Which I can work around by changing it to a long:
string x = "Hello";
long y = reinterpret_cast<long>(&x);
cout << *reinterpret_cast<string*>(y) << endl;
The C++ standard specifies minimums for these types, but not maximums, so you really don't know what you're going to be dealing with when you face a new compiler. See: What does the C++ standard state the size of int, long type to be?
So the potential for writing non-portable code is high once you start going this route and "casting away" the safeties in the language. reinterpret_cast is the most dangerous type of casting...
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
But that's just technically drilling down into the "why not int" part specifically, in case you were interested. Note that as #BenVoight points out in the comment below, there does exist an integer type as of C99 called intptr_t which is guaranteed to hold any poniter. So there are much larger problems when you throw away type information than losing precision...like accidentally casting back to a wrong type!
C++ is a strongly typed language, and pointers and integers are different types. By making those separate types the compiler is able to detect misuses and tell you that what you are doing is incorrect.
At the same time, the pointer type maintains information on the type of the pointed object, if you obtain the address of a double, you have to store that in a double*, and the compiler knows that dereferencing that pointer you will get to a double. In your example code, int y = &x; cout << *y; the compiler would loose the information of what y points to, the type of the expression *y would be unknown and it would not be able to determine which of the different overloads of operator<< to call. Compare that with std::string *y = &x; where the compiler sees y it knows it is a std::string* and knows that dereferencing it you get to a std::string (and not a double or any other type), enabling the compiler to statically check all expressions that contain y.
Finally, while you think that a pointer is just the address of the object and that should be representable by an integral type (which on 64bit architectures would have to be int64 rather than int) that is not always the case. There are different architectures on which pointers are not really representable by integral values. For example in architectures with segmented memory, the address of an object can contain both a segment (integral value) and an offset into the segment (another integral value). On other architectures the size of pointers was different than the size of any integral type.
The language is trying to protect you from conflating two different concepts - even though at the hardware level they are both just sets of bits;
Outside of needing to pass values manually between various parts of a debugger, you never need to know the numerical value.
Outside of archaic uses of arrays, it doesn't make sense to "add 10" to a pointer - so you shouldn't treat them as numeric values.
By the compiler retaining type information, it also prevents you from making mistakes - if all pointers were equal, then the compiler couldn't, helpfully, point out that what you're trying to dereference as an int is a pointer to a string.