Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing a char * with an expression does not work

The following code is producing the incorrect output:

string my_string="My_First_Text";
char * my_pointer=(char *)(my_string+"My_Second_Text").c_str();

Why? As I am initializing my_pointer, I presumed that no my_pointer=new char[100] is needed. If this assumption is not true, then why?

like image 326
Admia Avatar asked Jan 22 '17 06:01

Admia


People also ask

Can you initialize a string from a char *?

A more convenient way to initialize a C string is to initialize it through character array: char char_array[] = "Look Here"; This is same as initializing it as follows: char char_array[] = { 'L', 'o', 'o', 'k', ' ', 'H', 'e', 'r', 'e', '\0' };

What is a char * in C?

In C, char* means a pointer to a character. Strings are an array of characters eliminated by the null character in C.

Can you set a string to a char * C++?

You can't really "assign a string" to a char * , because although a char* parameter is sometimes referred to as a "string parameter", it isn't actually a string, it's a pointer (to a string). If you're getting heap corruption, then the problem isn't the assignment, the problem is your management of allocated memory.


2 Answers

Note that my_string+"My_Second_Text" is a temporary std::string, which will be destroyed after the expression immediately. That means my_pointer will become dangled at once, because the char array it's supposed to point to has been destroyed along with the destroy of the temporary std::string; note that the returned char array belong to std::string, it's not standalone. Then, deference on dangled pointer would lead to UB.

string my_string="My_First_Text";
char * my_pointer=(char *)(my_string+"My_Second_Text").c_str();
// the temporary constructed from my_string+"My_Second_Text" has been destroyed
// my_pointer is dangled now; deference on it is UB

Using named variable instead of temporary will be fine. e.g.

string my_string = "My_First_Text";
my_string += "My_Second_Text";
const char * my_pointer = my_string.c_str();

BTW: The return type of std::basic_string::c_str is const char*, and any modification on it is UB. So trying to convert it to char* explicitly is dangerous.

Writing to the character array accessed through c_str() is undefined behavior.

like image 69
songyuanyao Avatar answered Sep 21 '22 06:09

songyuanyao


Apart from casting the c_str (const char*) to a char*, which is not a good idea, "my_pointer" is initialized using a temporary, and is destructed after the expression is evaluated. meaning, just after the last ';' in your code.
This means that my_pointer points to memory that is no longer valid, and will have unexpected results.

like image 38
Moshe Gottlieb Avatar answered Sep 24 '22 06:09

Moshe Gottlieb