Строковые литералы типа const char[]
Обновлен: Ноябрь 2007
Строковые литералы теперь имеют тип 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 и Visual Studio .NET 2003, и нарушение прав доступа не будет возникать:
// 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);
}