更新:2007 年 11 月
字符串现在具有类型 const char [],并放在只读的内存节中。更改该内存现在将导致访问冲突。使用 /GF 在以前的版本中编译的代码也会导致访问冲突。
下面的示例可以在 Visual Studio .NET 中编译和运行,但在 Visual Studio .NET 2003 中将在运行时失败:
// bc_string_literals_have_proper_type_of_const_char.cpp
// compile with: /c
void f(char *c) {
c[0] = 'Q'; // Now gives run-time access violation
}
int main() {
f("TEST");
}
此外,像下面示例这样的代码的运行时行为现在已更改:
// bc_string_literals_have_proper_type_of_const_char2.cpp
#include "stdio.h"
void f(const char *) { // called in Visual Studio .NET 2003
printf_s("in f(const char *)\n");
}
void f(char *) { // called in Visual Studio .NET
printf_s("in f(char *)\n");
}
int main() {
f("TEST");
}
若要解决此错误,请不要将字符串传递到将在其中修改字符串的函数。
在采用这种方式重载函数的情况下,对于在当前版本和以前版本的 Visual C++ 中有效的代码:
将字符串显式强制转换为 const char*。
在堆栈或堆上定义变量。
下面的代码在 Visual C++ 的 Visual Studio .NET 2003 和 Visual Studio .NET 版本中有效,并且在任何一种版本中都不会导致访问冲突:
// bc_string_literals_have_proper_type_of_const_char3.cpp
#include <stdio.h>
void f(const char *psz) {
printf_s("const version\n");
}
void f(char *psz) {
printf_s("version where we modify it\n");
psz[0] = 'x';
}
int main() {
char myStr[] = "TEST";
f((const char*)"TEST");
f(myStr);
}