不推荐将字符串常量转换为'char*'

mah*_*ood 26 c++ string char

可能重复:
C++不推荐将字符串常量转换为'char*'

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

 char *Type = new char[10];
 Type = "Access";  // ERROR
Run Code Online (Sandbox Code Playgroud)

但是我收到此错误:

 error: deprecated conversion from string constant to 'char*'
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

Bal*_*arq 38

如果你真的想修改类型:

char *Type = new char[10];
strcpy( Type, "Access" );
Run Code Online (Sandbox Code Playgroud)

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

const char *Type = "Access";
Run Code Online (Sandbox Code Playgroud)

请注意,但是,C和C++中的char数组存在很多问题.例如,您实际上并不知道对new的调用是否成功,或者它是否会抛出异常.此外,strcpy()可能超过10个字符的限制.

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

std::string Type = "Access";
Run Code Online (Sandbox Code Playgroud)

如果你不想修改它:

const std::string Type = "Access";
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意,`strcpy()`不会检查目标中是否有足够的空间来复制值.如果字符串文字的长度超过9个字符,那么`strcpy()`调用会产生缓冲区溢出(编译器可能不会告诉你).哦,你应该在尝试复制到新分配的缓冲区之前验证`new`是否成功.真的,对于C++`std :: string`几乎可以肯定是一个更好的解决方案; 它有一些开销,但它会为你处理所有这些分配问题. (5认同)

Kei*_*son 12

这里有几件事情.

char *Type = new char[10];
Run Code Online (Sandbox Code Playgroud)

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

Type = "Access";  // ERROR
Run Code Online (Sandbox Code Playgroud)

这项任务不符合你的想法.它不会将6个字符的字符串"Access"(包括终止的7个字符'\0')复制到刚刚创建的数组中.相反,它将指向该数组的第一个元素的指针指向您的指针Type.这有两个问题.

首先,它破坏了先前的价值Type.你刚刚分配的那个10个字符的数组没有任何指向它的东西; 您无法再访问它甚至取消分配它.这是内存泄漏.

这不是编译器所抱怨的.

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

Type = "Access";
Type[0] = 'a'; // try to change the string to "access"
Run Code Online (Sandbox Code Playgroud)

目的const是阻止您修改甚至尝试修改只读的内容.这就是为什么不允许将非const指针值赋给const指针对象的原因.

由于您使用C++进行编程,因此最好使用它std::string.


Rob*_*obᵩ 5

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

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

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

int main() {
  f("Access");
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

int main() {
  f(const_cast<char*>("Access"));
}
Run Code Online (Sandbox Code Playgroud)

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

要么,

#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);
}
Run Code Online (Sandbox Code Playgroud)

但是,到目前为止最好的方法是避免整个指针mishegas:

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

int main() {
  f("Access");
}
Run Code Online (Sandbox Code Playgroud)