Поделиться через


Строковые литералы типа 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);
}

См. также

Ссылки

Критические изменения в компиляторе Visual C++