Replacing characters in C++ Pointer Character string? [duplicate] - c++

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 9 years ago.
Suppose I have this in C++:
char *p = "Apple";
I can't do this:
p[1] = 'w';
But why can I do this?
p = "OrangeTorange";

As p points to constant string literal so if you do: p[1] = 'w'; then you are trying to modifying string literal that is read only constant and its illegal operation (Undefined behavior).
Whereas in expression p = "OrangeTorange"; you modify value of p variable that is pointer to a char. And assigning new address value to p is a valid operation, now p start pointing to new string literal.
To add further, Suppose if p points an array then p[1] = 'w'; is not a invalid operation consider below example code:
char str[] = "Apple";
char* p = str; // p points to a array
p[1] = 'w'; // valid expression, not str[1] = 'w' is well valid.
p = "OrangeTorange"; // is valid
// str = "OrangeTorange"; is NOT valid as `str` is not a pointer but array name
Here both operations asked are valid!
Note: Two declarations char *str and char str[] are different. To understand it read: What does sizeof(&arr) return?

p[1] = 'w' is attempting to modify a string literal, which is illegal. p = "OrangeTorange" is just assigning a different string literal to p, which is fine.

You can't modify the original string because it's read-only data. You can modify the pointer to point to a different string because the pointer is modifiable. That is, p = "OrangeTorange" is not modifying the original string, only changing where the pointer p points to.

Related

understand how char works in c++ [duplicate]

This question already has answers here:
What happened when we do not include '\0' at the end of string in C?
(5 answers)
What is the difference between char s[] and char *s?
(14 answers)
Why do string literals (char*) in C++ have to be constants?
(2 answers)
Closed last year.
I am a C++ newbie. Although many similar questions have been asked and answered, I still find these concepts confusing.
I know
char c='a' // declare a single char c and assign value 'a' to it
char * str = "Test"; // declare a char pointer and pointing content str,
// thus the content can't be modified via point str
char str1[] = "Test"; // declare a char array str1 and assign "Test" to it
// thus str1 owns the data and can modify it
my first question is char * str creates a pointer, how does char * str = "Test"; work? assign a string literal to a pointer? It doesn't make sense to me although it is perfectly legal, I think we can only assign an address to a pointer, however "Test" is a string literal not an address.
Second question is how come the following code prints out "Test" twice in a row?
char str2[] = {'T','e','s','t'}; // is this line legal?
// intializing a char array with initilizer list, seems to be okay to me
cout<<str2<<endl; // prints out "TestTest"
why cout<<str2<<endl; prints out "TestTest"?
char * str = "Test"; is not allowed in C++. A string literal can only be pointed to by a pointer to const. You would need const char * str = "Test";.
If your compiler accepts char * str = "Test"; it is likely outdated. This conversion has not been allowed since C++11 (which came out over 10 years ago).
how does char * str = "Test"; work?
String literals are implicitly convertible to a pointer to the start of the literal. In C++ arrays are implicitly convertible to pointer to their first element. For example int x[10] is implicitly convertible to int*, the conversion results in &(x[0]). This applies to string literals, their type is a const array of characters (const char[]).
how come the following code prints out "Test" twice in a row?
In C++ most features related to character strings assume the string is null terminated, which is implied in string literals. You would need {'T','e','s','t','\0'} to be equivalent to "Test".

I thought string literal were read only? [duplicate]

This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 1 year ago.
char* a = "string"; /*"string" is a string literal, thus modifying
value isn't allowed, but then why */
char b[] = "string1"; /*"string1" is
also a string literal but why modification of this is allowed? */
a[1] = 's'; //this is not allowed b[1] = 'p'; //this is allowed
Why can char array be modified when it is clearly pointing to a string literal?
when it is clearly pointing to a string literal?
No. Given char b[] = "string1";, b is not a pointer pointing to the string literal, but a char array containing copy of "string1". The modification on the string literal leads to UB, but modification on the char array is fine.
String literals can be used to initialize character arrays. If an array is initialized like char str[] = "foo";, str will contain a copy of the string "foo".
BTW char* a = "string"; is not allowed since C++11; you have to write it as const char* a = "string";.

Why do we access the value of the bytes pointed at by the char* instead of the value of the pointers?

From previous questions in the topic, I've understood that the pointer points to the first character of a string, and expects the following characters to take part of the string until a null character.
My question is how does this declaration for example work:
const char* name = "abc";
As far as I understand, the value of the const char* isn't the phrase "abc", it's an integer which points to the location of the "a" character in my memory. This part is which I don't understand. Why?
Shouldn't we only be able to give value to a byte by dereferencing the pointer first?
const char* name = "abc";
is basically short for:
// compiler makes up a random name
static const char _abc_string_235o8v3tiue[4] = {'a', 'b', 'c', '\0'};
const char* name = _abc_string_235o8v3tiue;
which is short for:
// compiler makes up a random name
static const char _abc_string_235o8v3tiue[4] = {'a', 'b', 'c', '\0'};
const char* name = &_abc_string_235o8v3tiue[0];
Why? because thats what pointers do, their value is a memory adress. The type of "abc" is actually const char[4] (one for the null terminator). And arrays can decay to pointers to their first element.
Shouldn't we only be able to give value to a byte by dereferencing the pointer first?
No. To assign a value to an object you assign the value to the object. When you want to assign soemthing to what a pointer points to then you dereference the pointer:
int x;
int* y = &x; // <- initialize the pointer with address of x
*y = 5; // dereference y and assign 5 to x
For how the memory for the string literal is managed I refer you to this answer: https://stackoverflow.com/a/2740728/4117728

char *newx=p+strlen(str1); how this will execute because strstr will return the pointer to the first match character of the another string

I can not understand how this code will execute. As far as I know, strstr() will return a pointer to the first letter of the matching string. So, how can we do char *newx=p+strlen(str1); when p is a pointer and strlen() returns an integer value?
p=strstr(str2,str1);
if(p){
char *newx=p+strlen(str1);
strcpy(t,newx);
}
This is simple pointer arithmetic.
Adding an integer to a pointer increments the pointer by the specified number of elements.
Say you have a pointer T *ptr. When you do something like this:
T *ptr2 = ptr + N;
The compiler actually does (an optimized) equivalent of this:
T *ptr2 = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(ptr) + (sizeof(T) * N));
So, the code in question is using strstr() to search the str2 string for a substring str1 and get a pointer to that substring. If the substring is found, that pointer is then incremented via strlen() to the address of the character immediately following the end of the substring, and then strcpy() is used to copy the remaining text from that address into the t string.
For example:
const char *str2 = "Hello StackOverflow";
const char *str1 = "Stack";
const char *p;
char t[10];
p = strstr(str2, str1); // p points to str2[6]...
if (p) { // substring found?
const char *newx = p + strlen(str1); // newx points to str2[11]...
strcpy(t, newx); // copies "Overflow"
}
This is a question regarding pointer arithmatic. I suggest you read https://www.tutorialspoint.com/cplusplus/cpp_pointer_arithmatic.htm for more info on pointer arithmatic.
For this question, the clarification is, when you add the size of the str1 to newx, it automatically identifies that you're incrementing a char pointer and hence the address needs to be incremented by sizeof(char) * strlen(str1)
Hope this clarifies on your issue and highly recommend you to read through pointer arithmatic.

Does char *a[] ={"yes","no"} requires malloc? [duplicate]

This question already has answers here:
String literals: Where do they go?
(8 answers)
Closed 4 years ago.
statements like: char *a = "hello" or char *b[]= {"yes", "no"} seem to be accessible and printable without any problems in C.
Do they require a malloc?
Case 1 :- char *a = "hello"; Here a is char pointer and it needs valid address and its assigned with valid address as hello is string i.e address. So no need of malloc() here.
Case 2 :- char *b[]= {"yes", "no"}; Here b is array of char pointer i.e each element of b is pointer that means each elements needs to be initialized with valid address and its assigned with valid address as b[0] with yes(i.e address) and b[1] with no(i.e address). So here also no need of malloc().
"hello" here is string constant which is residing in data segment which is readable section of memory.
char *a ="hello" is nothing but you are assigning the address of const string "hello"
to char pointer a.
if you try to modify content of this const string using ptr a it will crash.
e.g
a[1]= 'E' /// -> this is undefined behavior
If you want to own memory then malloc and copy string into memory created using malloc.