【问题标题】:deprecated conversion from string constant to 'char*' [duplicate]不推荐将字符串常量转换为“char *”[重复]
【发布时间】:2011-12-28 22:00:19
【问题描述】:

可能重复:
C++ deprecated conversion from string constant to 'char*'

我想通过 char* 将字符串传递给函数。

 char *Type = new char[10];
 Type = "Access";  // ERROR

但是我得到了这个错误:

 error: deprecated conversion from string constant to 'char*'

我该如何解决这个问题?

【问题讨论】:

  • 如果你覆盖Type你会产生内存泄漏。
  • 任何关于“修复”的建议都可能会忽略这样一个事实,即你很可能没有理由去做你正在做的事情。发布更大的图片以获得更有用的答案。
  • 复习一下指针是如何工作的。 (如果您还没有处理过指针,请查看它们。)您不会分配给像 char Type[10]; Type = "Access"; 这样的数组吧?

标签: c++ string char


【解决方案1】:

如果真的要修改Type:

char *Type = new char[10];
strcpy( Type, "Access" );

如果您不想修改访问权限:

const char *Type = "Access";

请注意,然而,C 和 C++ 中的 char 数组会带来很多问题。例如,你真的不知道对 new 的调用是否成功,或者它是否会抛出异常。此外,strcpy() 可能会超过 10 个字符的限制。

所以你可以考虑,如果你以后想修改类型:

std::string Type = "Access";

如果你不想修改它:

const std::string Type = "Access";

...使用std::string 的好处是它能够应对所有这些问题。

【讨论】:

  • 请注意,strcpy() 不会检查目标中是否有足够的空间用于复制的值。如果字符串文字的长度超过 9 个字符,strcpy() 调用将创建缓冲区溢出(编译器可能不会告诉您)。哦,在尝试复制到新分配的缓冲区之前,您应该验证new 是否成功。真的,对于 C++,std::string 几乎可以肯定是一个更好的解决方案;它有一些开销,但它会为您处理所有这些分配问题。
  • 是的,@Keith Thompson,这是一个很好的观点。我会修改我的答案以接受它。
【解决方案2】:

我想通过 char* 将字符串传递给函数。

以下是如何通过 char* 将字符串传递给函数(注意函数签名中必需的 const 关键字。)

#include <iostream>
void f(const char* p) {
  std::cout << p << "\n";
}

int main() {
  f("Access");
}

但是,如果您正在调用现有函数,并且无法修改其签名怎么办?

如果你有一些外部保证,函数不会通过它的参数指针写入,

#include <iostream>
void f(char* p) {
  std::cout << p << "\n";
}

int main() {
  f(const_cast<char*>("Access"));
}

另一方面,如果函数可能写入字符串,那么您需要为字符串分配空间:

#include <iostream>
void f(char* p) {
  *++p;
  std::cout << p << "\n";
}

int main() {
  // Allocate read-write space on the heap
  char *p = new char[strlen("Access"+1)];
  // Copy string to allocated space
  strcpy(p, "Access");
  f(p);
  delete p;
}

或者,

#include <iostream>
void f(char* p) {
  *++p;
  std::cout << p << "\n";
}

int main() {
  // Allocate read-write space on the stack
  char arr[] = "Access";
  f(arr);
}

但是,目前最好的做法是避免整个指针 mishegas:

#include <iostream>
void f(const std::string& p) {
  std::cout << p << "\n";
}

int main() {
  f("Access");
}

【讨论】:

  • 你是对的。我忘了编辑第一行。感谢您的信息
【解决方案3】:

这里有一个基本的操作问题,而不是编码问题。

当您想要更改 C char 数组的内容时,您不要使用赋值运算符。这将改变底层指针的值。艾克。

相反,您应该使用 C 字符串库例程。例如,strcpy (Type, "Access"); 会将字符串文字“Access”复制到您的字符数组中,并使用其最重要的尾随 nul 字符。

如果您使用的是 C++(如您的标签所示),您可能应该使用 std::string 而不是 char 数组。分配按您期望的方式进行。

【讨论】:

    【解决方案4】:

    这里发生了几件事。

    char *Type = new char[10];
    

    这将创建一个名为 Typechar* 指针并将其初始化为指向新分配的 10 元素数组的第一个元素。

    Type = "Access";  // ERROR
    

    这个作业没有做你认为它做的事情。它不会将 6 个字符的字符串 "Access"(包括终止 '\0' 在内的 7 个字符)复制到您刚刚创建的数组中。相反,它将一个 pointer 分配给该数组的第一个元素到您的指针 Type。这样做有两个问题。

    首先,它破坏了Type 的先前值。您刚刚分配的 10 个字符的数组现在没有任何指向它;你不能再访问它甚至释放它。这是内存泄漏。

    这不是编译器所抱怨的。

    其次,字符串字面量创建一个静态分配的 const 数组(“静态分配”意味着它存在于程序的整个执行过程中)。 Type 未使用 const 限定符声明。如果编译器允许您将Type 指向字符串"Access",您可以使用该指针来(尝试)修改它:

    Type = "Access";
    Type[0] = 'a'; // try to change the string to "access"
    

    const 的目的是防止您修改,甚至试图修改只读内容。这就是为什么不允许将非常量指针值分配给 const 指针对象的原因。

    由于您使用 C++ 进行编程,因此使用 std::string 可能会更好。

    【讨论】:

    • @Rob:谢谢。那会教我在喝咖啡之前发帖!
    • +1。很好的解释。这有助于 OP
    猜你喜欢
    • 2011-11-20
    • 2011-11-16
    • 2012-09-09
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 2012-08-28
    • 2013-05-21
    • 2012-03-27
    相关资源
    最近更新 更多