Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conversion from string literal to char* is deprecated

Tags:

c++

string

char

I keep getting the error "Conversion from string literal to char* is deprecated" in my code. The purpose of the code is to use a pointer-to-pointer to assign string1 and string2 a word, then print it out. How can I fix this?

Here is my code:

#include <iostream> using namespace std;  struct WORDBLOCK {     char* string1;     char* string2; };  void f3() {     WORDBLOCK word;      word.string1 = "Test1";     word.string2 = "Test2";       char *test1 = word.string1;     char *test2 = word.string2;      char** teststrings;      teststrings = &test1;     *teststrings = test2;      cout << "The first string is: "          << teststrings          << " and your second string is: "          << *teststrings          << endl;   } 
like image 562
Andrew T Avatar asked Dec 03 '12 19:12

Andrew T


People also ask

Can you change a string literal?

The behavior is undefined if a program attempts to modify any portion of a string literal. Modifying a string literal frequently results in an access violation because string literals are typically stored in read-only memory.


1 Answers

C++ string literals are arrays of const char, which means you can't legally modify them.

If you want to safely assign a string literal to a pointer (which involves an implicit array-to-pointer conversion), you need to declare the target pointer as const char*, not just as char*.

Here's a version of your code that compiles without warnings:

#include <iostream>  using namespace std;  struct WORDBLOCK {     const char* string1;     const char* string2; };  void f3() {     WORDBLOCK word;      word.string1 = "Test1";     word.string2 = "Test2";      const char *test1 = word.string1;     const char *test2 = word.string2;      const char** teststrings;      teststrings = &test1;     *teststrings = test2;      cout << "The first string is: "          << teststrings          << " and your second string is: "          << *teststrings          << endl; } 

Consider what could happen if the language didn't impose this restriction:

#include <iostream> int main() {     char *ptr = "some literal";  // This is invalid     *ptr = 'S';     std::cout << ptr << "\n"; } 

A (non-const) char* lets you modify the data that the pointer points to. If you could assign a string literal (implicitly converted to a pointer to the first character of the string) to a plain char*, you'd be able to use that pointer to modify the string literal with no warnings from the compiler. The invalid code above, if it worked, would print

Some literal 

-- and it might actually do so on some systems. On my system, though, it dies with a segmentation fault because it attempts to write to read-only memory (not physical ROM, but memory that's been marked as read-only by the operating system).

(An aside: C's rules for string literals are different from C++'s rules. In C, a string literal is an array of char, not an array of const char -- but attempting to modify it has undefined behavior. This means that in C you can legally write char *s = "hello"; s[0] = 'H';, and the compiler won't necessarily complain -- but the program is likely to die with a segmentation fault when you run it. This was done to maintain backward compatibility with C code written before the const keyword was introduced. C++ had const from the very beginning, so this particular compromise wasn't necessary.)

like image 160
Keith Thompson Avatar answered Oct 04 '22 08:10

Keith Thompson