Windows Programmer
Windows Programmer

Reputation: 103

Query on Pointer dereferencing

I was doing some some string manipulation and encountered with a problem.

 char *arr1 = "HELLO";
 (*arr1)++;

this throws an error "Access violation writing to location"!

however, below code works fine.

 char arr1[] = "HELLO";
 (*arr1)++;

and what are their memory segments on which both the char* arr1 and char arr1[] are stored ?

Upvotes: 0

Views: 45

Answers (5)

marcinj
marcinj

Reputation: 49976

Literals like "HELLO" are of type const char[] which decays to const char*, compiler can put it in memory which actually cannot be modified, modification results in undefined behaviour. g++ gives you warning like below:

main.cpp:7:14: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

 char *arr1 = "HELLO";

Compiler allows this because as your can read here (http://en.cppreference.com/w/cpp/language/string_literal):

In C, string literals are of type char[], and can be assigned directly to a (non-const) char*. C++03 allowed it as well (but deprecated it, as literals are const in C++). C++11 no longer allows such assignments without a cast.

but actually I dont get errors on g++ even with C++11 enabled.

arrays of course you can modify, so your second example works fine. This code:

char arr1[] = "HELLO";

creates on stack an array of length 6 and initializes it with "HELLO\0"

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385108

You didn't do any pointer arithmetic. You dereferenced the pointer then incremented the thing it points to (the first character).

Unfortunately for you, string literals cannot be modified (and you should have been warned by your compiler that char* is bad and const char* is good, for pointing to string literals).

It works in the second case because initialising a local array from a string literal creates your own copy of the data.

Upvotes: 0

user2672107
user2672107

Reputation:

There is no pointer arithmetic. You are adding one to the first charachter of the string. Since string constants are not writable, the first version gives an error. In the second version you change the content of on char array, so there is no problem.

Upvotes: 0

abacabadabacaba
abacabadabacaba

Reputation: 2692

In the first case, arr1 is a local variable which holds a pointer to a read-only memory segment containing the string "HELLO". The statement (*arr1)++ tries to modify the first byte of the segment (which contains the character 'H'), which leads to access violation.

In the second case, arr1 is a local variable which holds an array of six bytes, which are initialized with {'H', 'E', 'L', 'L', 'O', 0}. Local variables are in read-write memory, so modifying them doesn't lead to an error.

Upvotes: 0

Raj
Raj

Reputation: 4452

 char *arr1 = "HELLO";

The above definition implies that the memory for arr1 could be allocated in a read-only part of memory (it is implementation-defined behaviour, actually), and thus could cause 'Access violation' when you are trying to change the value at the memory location is pointing to.

char arr1[] = "HELLO";

In this case, the memory for arr1 is allocated in stack - which is writable. Hence, the expression (*arr1)++ works fine without any issue.

Upvotes: 2

Related Questions