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 :'(.

Recommended Answers

All 49 Replies

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.

1. Look at this:
char *str = "Literal String";

2.
char x = 's';

1. This is creating a pointer to a char, writting "Literal String" at that address in memory

2. This is creating a char in memory, and assigning the value of 's' to it.

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??

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??

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??

> 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.

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?

Right, but again it is implementation specific. The language doesn't mandate it.

YaY thank you very much all !!!

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.)

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?

...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"

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??

#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.

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?

Nope - they point somewhere at compile time.
The problems start at run-time when you try and dereference the pointers.

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??

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?

You dont understand me do you?

All i ask is

char *ptr = "Hi";
*ptr = 'x';

Why here the compiler doesnt give any errors???

char *ptr = "Hi";

We creating a pointer then we giving to some block of memory this values {'H','i','\0'} and giving to ptr the address of 'H' ?(First value).

But here:
*ptr = 'x';

Here why the compiler doesnt give any error??
Why why why???
This is my question...

If "Literal String" is type of Arrays of const chars.
and We are trying to modify it here *ptr = 'x';
Why the compiler doesnt give any error??
We are trying to modify a constant value.....
Why the compiler treats it normal???
This is the question!!

Is it Because pointers are pointing to data at run-time, and not at the compile time???

because it is modifying the first character of your string... why don't YOU understand?? in that case, the value in ptr is the address of the first character of the string, so, when you assign the pointer to that address a different character, you are changing the first letter of your string

Why would it give you an error?

You said 'char*' and not 'const char*', so it's perfectly reasonable from a syntactic point of view to allow you to modify what it points to.

char foo[] = "hello";
char *p;

p = foo;
*p = 'H';  // no problem here
p = "world";
*p = 'W';  // danger Will Robinson!

Like I said in a previous post, the 'const'ness of a "Literal string" is silently dropped when you do
char *p = "Literal";
Whatever information there was to allow the compiler to report a problem has been lost.

Why would it give you an error?

You said 'char*' and not 'const char*', so it's perfectly reasonable from a syntactic point of view to allow you to modify what it points to.

thank you... thank you very very much...

that's what i've been trying to say all along...

get it now?

Dont you see??

char *str = "HI";
*str = 'z';
In this case the program will crash with bus error on RunTime !! TEST IT YOUR SELF!!!

1.Or its will crash with runtime error.
2.Or its just will not change the value because "Literal String" is constant (ReadOnly) and its wont give you the access to change it ...

Just try..

let me explain what is going on here.

char *str = "HI";
*str = 'z';

The compiler compiles it because he is DUMB he doesnt know that str is pointing to the first element of the string "HI" (Pointers pointing only at the RunTime).

if he would knew that str is pointing to the first element of the string "HI" then he would throw errors because "HI" is a literal string and a literal string made of arrays of const chars and we cant modify it (*str = 's';).

So the compiler convert it to .exe file executable file then when we open it runing the program (RunTime) The code is executed.

we are alocating memory for the pointer and then we are alocating memory for the string "HI" then we are setting str point to the first element of this string.
Now when we are trying to modify it *str = 's'; the program crashes or doesnt modifying the value..

Now tell me am i right?

char* str = "Literal"; Though the above is a constant string literal, nothing prevents you from modifying it. The compiler has no way of enforcing it at compile time. To make the compiler know that this is a string literal which shouldn't get modified, we write: const char* str = "Literal"

memory for a literal string is pre-allocated (that is what static storage means). usually the memory is pre-allocated as read only.

you may be able to modify the way the compiler works by using compiler options. eg. in gcc you could use the option -fwritable-strings. this is what gcc documentation has to say about this:
-fwritable-strings
Store string constants in the writable data segment and don't uniquize them. This is for compatibility with old programs which assume they can write into string constants. Writing into string constants is a very bad idea; “constants” should be constant. This option is deprecated.

the following example may clarify things:

int main()
{
  // c1(stack) is a logical const, not a physical const
  const int c1 = 4 ;    // stack is writable at run-time
  const_cast<int&>(c1) = 200 ;  // so this wont cause a run-time fault 

  // c2 (SDA) requires dynamic init, can't be in readonly memory
  static const int c2 = strlen("abcd") ; // logical, not physical const
  const_cast<int&>(c2) = 200 ;  // so this too wont cause a run-time fault 

  // any decent compiller  will place c3 into the read-only portion of SDA
  static const int c3 = 4 ;  // logical and physical const
  
  // uncomment this & there will be a run-time fault
  //const_cast<int&>(c3) = 200 ;   
}

I use "Microsoft Visual C++ 2005 Express Edition".

and with this compiler i cant modify "Literal strings" because they are constants.

So in my compiler if i do this:
char *str = "Literal String";
*str = 'X';
cout << str;

the output is still:
"Literal String"
and not
"Xiteral String"

even if we did *str = 'X';

So it means that i cant modify the strings at my compiler.

Now you can understand that my compiler doesnt modifying literal strings because they are constants.

And now maybe someone can explain me how this compiles:

Note:In my compiler i cant modify literal strings because they are constants.

char *str = "string";
*str = 'z';

Is it because the compiler doesnt know what value pointed by ptr at the Compiling-Time (Pointers pointing only at runtime).
And this is why its crashes at the RunTime?
because we modifying constant string??

Is it because of this??

> And now maybe someone can explain me how this compiles:
> Note:In my compiler i cant modify literal strings because they are constants.
> char *str = "string"; // drops const
> *str = 'z';
I've already said this twice already.
You lost the 'const' in the assignment - this is a feature of C and C++ to cater for old code.
As soon as the const is lost, the compiler loses the ability to tell you that you've screwed up.

If you want to be correct, and let the compiler warn you, always say const char *str = "string"; Then when you try *str = 'z'; You'll get a message from the compiler.

> Is it because the compiler doesnt know what value pointed by ptr at the Compiling-Time
The compiler knows where it points.
What it doesn't know is that it really is const, because you washed the const away with the previous assignment.

It boils down to this.
If you lie about the code, then don't expect the compiler to spot everything you do.

> And this is why its crashes at the RunTime?
> because we modifying constant string??
Yes, the OS steps in and kills your program dead.
Do not pass go, do not collect $200 kinda thing.

Ok you explained me all very nice
i'm getting everything now except
why here the const is droped?

char *str = "string";

can you explain it more specific here?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.