Необработанное исключение при разыменовании указателя char в Visual C ++ 2008

StackOverflow https://stackoverflow.com/questions/1114237

Вопрос

Я пытаюсь выполнить некоторую классическую разработку на C в Visual C ++ 2008, которая изменит символы строки следующим образом:

void ModifyString(char *input)
{
  // Change first character to 'a'
  *input = 'a';
}

Я получаю необработанное исключение, когда пытаюсь изменить символ.Кажется, я мог бы сделать это в Visual Studio 6 или с помощью gcc, но, возможно, я просто что-то забываю.Передает ли Visual Studio каким-либо образом char * по значению (управление памятью).Если да, то как мне это отключить?

Это было полезно?

Решение

Вероятно, вы где-то передаете строковый литерал:

ModifyString("oops");  // ERROR!

C и C ++ позволяют вам неявно выполнять приведение из строковых литералов (которые имеют тип const char[]) к char*, но такое использование устарело.Строковые константы разрешено размещать в памяти, доступной только для чтения (и обычно так и есть), поэтому, если вы попытаетесь их изменить, вы получите нарушение доступа (оно же ошибка сегментации или шины).Если компилятор не помещает строковые константы в память, доступную только для чтения, программа все равно будет работать, но это неопределенное поведение.

Правильный способ сделать это - скопировать строку в буфер, доступный для записи:

// one way:
char mystring[] = "test";
ModifyString(mystring);  // ok

// another way:
char mystring[64];  // make sure this is big enough!!
strcpy(mystring, "test");
ModifyString(mystring);  // ok

Другие советы

Является ли ввод строковым литералом?Вероятно, в этом-то и проблема.В противном случае вам нужно будет опубликовать больше кода, так как указатель каким-то образом оказался указывающим на место в памяти, доступное только для чтения.

Невозможно ответить на этот вопрос, не увидев, как вызывается ModifyString .Сама функция верна, предполагая, что ее контракту должно быть передано ненулевое значение.

Однако сайт вызова может выйти из строя, выполнив любое количество действий

  • Передача NULL
  • Передача const char с помощью злого приведения

Я не могу точно сказать, почему это не работает, но проблема в вашем коде, а не в Visual Studio.По какой-то причине вы передаете недопустимый указатель на функцию.Это либо нулевой указатель, либо он указывает на какой-то адрес, к которому у вас нет доступа на чтение.

Если вы опубликуете еще немного кода (откуда вызывается функция и как она вызывается?), мы, возможно, сможем указать на точную проблему.

Причина, по которой это сработало в GCC или VC6, довольно проста: это неопределенное поведение.Стандарт C ++ не говорит, что "это должно сработать" или "это должно вызвать сбой".Все может случиться, если вы будете записывать в память, к которой у вас нет доступа.И в зависимости от компилятора и системы, на которой вы запускаете приложение, адрес, к которому вы в конечном итоге получаете доступ, будет отличаться.По чистой случайности вы попали по адресу, который вызвал нарушение доступа при компиляции с помощью VC2008.В GCC и VC6 вам повезло меньше, и вы получили код, который казалось, сработало, и просто написал на какой-то мусорный адрес.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top