Help needed :(
I just started mess with Memory at c++ so i am very confused now, and this is why i am asking 3 questions that made me confuse so much.
1. Look at this:
char *str = "Literal String";
Here we are creating a char pointer called str then we are giving to some CELLS in memory this values "Literal String" and setting str to point on the first element at this memory block.
so it means that this expression "Literal String" returns an address of the first element in this memory block to str everywhere??
or its just in char pointers case??
2.
and what is going on here?
char x = 's';
We are giving to some CELL in memory a name X and then we are giving to this CELL the value 's'??
Or we are giving to some CELL in memory a name X then we are giving to some CELL this value 's' and then we are copying the value 's' from this CELL to the CELL X??
What is the correct answer here??
3.
And what is this?
void main()
{
"Literal String";
}
Here we are just giving to some CELLS in memory this values "Literal String" ???
and thats all??
I very need answers to this questions because when i started mess with memory its made me very very confused and i cant understand a thing now :'(.
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
1. The expression "Literal string" is a cute way of writing a memory address that points to to the front of an array of bytes, somewhere, whose contents are "Literal string". Except when initializing an array.
2. Both of those produce equivalent behavior, nyes?
3. Your program doesn't do anything; why would the compiler treat it any differently from void main() { } ? And main is supposed to return an integer.
Rashakil Fol
Super Senior Demiposter
2,658 posts since Jun 2005
Reputation Points: 1,135
Solved Threads: 177
So here
char *str = "Literal String";
we creating a pointer str and then pointing it to "Literal String" and thats all?
we are not creating "Literal String" first and then pointing??
or its already loaded in the program like numbers 1234??
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
Aha i got it
char *ptr = "Hello world";
the compiler automatically puts a null-character at the end of the literal string of characters "Hello world". It then creates a storage space for the resulting string - this is an array of const chars
and gives the ptr an address of the first element.
can you just tell me if its correct??
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
One more question please ;)
here
char* szFirst = "Literal String";
char* szSecond = "Literal String";
szFirst[3] = 'q';
printf("szFirst (%s) is at %d, szSecond (%s) is at %d\n",
szFirst, szFirst, szSecond, szSecond);
The addresses are the same is it because when we declared this pointer
char *szFirst = "Literal String"
We also gave to some CELLS in memory this values "Literal String"
and then setting szFirst point at the first element there.
now if we want to use the same string "Literal String" the compiler wont let us to create another copy so he gives us the already declared string??
Its all i need to know guys.
Am i right here??
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
> szFirst[3] = 'q';
This is a really bad idea.
Literal strings can be made read-only by the implementation. So whilst you might be able to modify a string, all it will do for me is stop the program dead.
> The addresses are the same
Again, this is something which is implementation specific. A compiler is allowed to merge identical string literals, so all references to it are to a single unique string (and not one of many identical copies).
Neither of these properties matter if you don't try to modify a string literal.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
So if we declare string literal once
for example here
1.
char *ptr = "String Literal";
and then i will try to use it again
2.
char *ptr2 = "String Literal";
The compiler sees that in 1 we already gave to "String Literal" a place in memory so the compiler dont want to create one more copy, and just giving to ptr2 the address of the already exist "String Literal"??
i mean
if you use identical strings to allocate string buffers, the compiler pools the strings. Thus, what was intended as multiple pointers to multiple memory places ends up as multiple pointers to a single memory place.
and it does it because it wont that our program will take more RAM.
Is it right?
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
Right, but again it is implementation specific. The language doesn't mandate it.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
YaY thank you very much all !!!
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
as a matter of principle, do not write
char *ptr = "String Literal";
even if your compiler does not complain about it.
instead always write
const char* ptr = "String Literal";
const char* const ptr2 = "another literal" ; // more usual
programming is much simpler if you habitually do the correct thing. and const-correctness is something most programmers find difficult to get right at a late stage in their programming career. (if you have any doubts about this, just take a look at code snippets / tutorials / replies to threads in this site.)
vijayan121
Posting Virtuoso
1,606 posts since Dec 2006
Reputation Points: 1,159
Solved Threads: 287
There is one more thing i wanted to know.
char* str = "hi";
*str = 's';
cout << str;
I know its not a good idea to do this:
*str = 's';
because the compiler saves the literal string "hi" in memory that cant be modifed.
But anyway i was wondering why its compiles??
If the literal string "hi" is constant and here we are trying to change/modify the constant:
*str = 's';
someone know?
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
...i was wondering why its compiles?? ... If the literal string "hi" is constant and here we are trying to change/modify the constant:
*str = 's';
someone know?
this is what the c++ standard states:
1 A string literal is a sequence of characters (as defined in _lex.ccon_) surrounded by double quotes, optionally beginning with the letter L, as in "..." or L"...". A string literal that does not begin with L is an ordinary string literal, also referred to as a narrow string literal.An ordinary string literal has type "array of n const char" and static storage duration, where n is the size of the string as defined below, and is initialized with the given characters. A string literal that begins with L, such as L"asdf", is a wide string literal. A wide string literal has type "array of n const wchar_t" and has static storage duration, where n is the size of the string as defined below, and is initialized with the given characters.
2 Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-defined. The effect of attempting to modify a string literal is undefined.
since the standard states that string literal has type "array of n const char", typing it as a char* is incorrect; a conformant implementation could (should? i would say so) give a compile-time error for
char* str = "literal"
vijayan121
Posting Virtuoso
1,606 posts since Dec 2006
Reputation Points: 1,159
Solved Threads: 287
I still dont get it how the compiler compiles it
char *str = "String";
*str = 'Z';
I understand this
char *str = "String";
but here
*str = 'Z';
we are trying to modify the first element
but those elements are constant.
I need to understand why its compiles, if we are trying to modify something constant??
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
#include <iostream>
using namespace std;
int main ( ) {
char *s = "hello";
const char *w = "world";
s[0] = 'H';
w[0] = 'W'; // line 8
return 0;
}
Result
$ g++ foo.cpp
foo.cpp: In function `int main()':
foo.cpp:8: error: assignment of read-only location
Here, const is being enforced by the compiler, because the pointer was declared "const char*".
Now comment out the offending assignment.
#include <iostream>
using namespace std;
int main ( ) {
char *s = "hello";
const char *w = "world";
s[0] = 'H';
//w[0] = 'W'; // line 8
return 0;
}
Result
$ g++ foo.cpp
$ ./a.exe
18 [main] a 3192 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)
Here, const is being enforced by the OS. Trying to modify something in read-only memory just kills the program.
In new code, you should always do const char *msg = "hello world";
This (and only with char*) is allowed for backward compatibility with a hell of a lot of old code. char *msg = "hello world";
With any other type, you'll get a 'loss of const' in assignment type warning or error.
Just because you can compile something without error messages doesn't mean it will run successfully.
Nor does a successful run imply that the program is bug-free.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
I think i got it.
The compiler doesnt give any errors because:
The pointers doesnt point anywhere at COMPILE-TIME but they do point at RUN-TIME !!!!!!!
CorrecT?
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
Nope - they point somewhere at compile time.
The problems start at run-time when you try and dereference the pointers.
Salem
Posting Sage
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
I dont think so.
Pointers cant point at the compile time.
because the program starts when we start it.
When we compile the compiler packing it at .exe file.
Then when we opening the .exe or another format this happens:
char *ptr = "Hi";
*ptr = 'X';
The compiler compiles it because he doesnt know what value pointed by ptr (Pointers pointing only at runtime).
Then when we are Opening the program (RunTime) the program taking memory in place for the pointer then Giving to some memory block this values "Hi";
And assigning the address of the first element to the pointer.
And when we are trying to modify the value pointed by ptr (*ptr = 'x').
The system crashes because we cant modify constant values.
But if the pointers at pointing at the compiling time like you said.
Its just wont compile.
Because first we would assigning the address of "Hi" first element to ptr.
Now the compiler knows that the value pointed by it is constant.
Then *ptr = 'x'; , the compiler wont compile it because he knows that the value pointed by ptr is constant...
So the result is "Pointers pointing at the Run-Time only...."
True??
laconstantine
Junior Poster in Training
70 posts since May 2007
Reputation Points: 10
Solved Threads: 1
first of all... i think it is very clear in the rules for posting that you shouldn't name your thread with names such as "help", or things like that...
second, think yourself as memory as a huge shelf,a pretty huge shelf, where you save information in bit sized boxes... when you create a pointer, you are telling the compiler to look for an empty shelf to start writing... when the compiler does this, information is stored in these shelves, so, your *ptr withdraws the information in your shelf...
in case of strings, your pointer will grab a group of shelves, which will store one character each, so, when you do this:
char *ptr="Literal String";
*ptr will return 'L', so... what happens when you tell the compiler to assign to *ptr another character (lets say 'd')? When you print your string, it should say "diteral String"
why? because your variable ptr is pointing to the first character in your string... you shouldn't manipulate a pointer to a string as it was stored in the same place in memory, because, what a pointer to a string does in memory is that takes the first "shelf" to store the first character, and then continues into other shelves...
get the idea?
Nichito
Posting Virtuoso
1,602 posts since Mar 2007
Reputation Points: 424
Solved Threads: 57