【问题标题】:Conversion from string literal to char* is deprecated不推荐从字符串文字到 char* 的转换
【发布时间】:2012-11-21 08:02:48
【问题描述】:

我的代码中不断出现错误“从字符串文字转换为 char* 已弃用”。该代码的目的是使用一个指向指针的指针来为 string1 和 string2 分配一个单词,然后将其打印出来。我怎样才能解决这个问题?

这是我的代码:

#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;  
}

【问题讨论】:

标签: c++ string char


【解决方案1】:

C++ 字符串文字是 const char 的数组,这意味着您不能合法地修改它们。

如果您想安全地将字符串文字分配给指针(这涉及到隐式数组到指针的转换),您需要将目标指针声明为const char*,而不仅仅是char*

这是您的代码的一个版本,可以在没有警告的情况下编译:

#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;
}

考虑一下如果语言没有施加这个限制会发生什么:

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

A(非constchar* 允许您修改指针指向的数据。如果您可以将字符串文字(隐式转换为指向字符串第一个字符的指针)分配给普通的char*,您就可以使用该指针来修改字符串文字,而不会来自编译器的警告。上面的无效代码,如果有效,将打印

Some literal

-- 它实际上可能在某些系统上这样做。但是,在我的系统上,它会因分段错误而死,因为它尝试写入只读内存(不是物理 ROM,而是被操作系统标记为只读的内存)。

(旁白:C 对字符串文字的规则与 C++ 的规则不同。在 C 中,字符串文字是 char 的数组,不是 const char 的数组——但尝试修改它有未定义的行为。这意味着在 C 中你可以合法地写char *s = "hello"; s[0] = 'H';,编译器不一定会抱怨——但是当你运行它时,程序很可能会因分段错误而死。这样做是为了保持与在引入 const 关键字之前编写的 C 代码的向后兼容性。C++ 从一开始就有 const,因此不需要这种特殊的妥协。)

【讨论】:

  • 那是令人难以置信的清晰、足智多谋和启发性。谢谢你的帮助,我现在明白多了!
  • 解释很好,但代码不清楚且令人困惑-看起来您希望在实际打印测试字符串的值时打印“Test1”和“Test2”(指向@的偏移量987654336@) 和test1 指向的字符串(即“Test2”,因为您通过测试字符串修改了test1
  • @neuviemeporte:(我知道我回复有点晚了。)我所做的只是在 OP 的代码中添加所需的 const 关键字。我没有尝试进行任何其他更正或改进。
  • 你不是说“不是 const char 的数组——”吗?
  • 尽管字符串文字从一开始就在 C++ 中为 const,但 C++03 及更早版本似乎将 allowed 隐式转换为 char *
猜你喜欢
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2014-04-21
  • 2010-12-04
  • 2013-05-21
  • 2016-05-30
  • 1970-01-01
相关资源
最近更新 更多