Нарушение памяти программы C - PullRequest
0 голосов
/ 28 февраля 2011

У меня есть программа ниже, где память только для чтения, но я все еще могу писать в нее.

main()
{
char *p="amit";
p[0]="s";
printf("%s",p);
}

Вывод "smit"

Это ожидаемый выводпоскольку p указывает местоположение, доступное только для чтения?Когда я запускаю эту программу в GCC или Visual C ++, я получаю ошибку сегментации, но в Turbo C ++ я получаю "smit".

Пожалуйста, подтвердите это поведение ...

Ответы [ 6 ]

3 голосов
/ 28 февраля 2011

Запись в строковый литерал дает неопределенное поведение, поэтому компилятору разрешается делать все, что он захочет, когда вы это делаете.

Простой ответ заключается в том, что Turbo C ++ компилируется для реального режима, поэтому ни один изпамять защищена.Ни компилятор, ни ОС не помешают вам что-либо писать.

3 голосов
/ 28 февраля 2011

Неопределенное поведение - это неопределенное поведение: что бы вы ни получали, вы не можете жаловаться.

Строковые литералы раньше были в записываемой памяти.Старые компиляторы имеют такое поведение.Некоторые компиляторы (по крайней мере, более старые версии gcc, кажется, были удалены в версии 4.X) имеют возможность получить его.Я рекомендую не использовать его, за исключением портирования старых приложений в зависимости от него.

1 голос
/ 28 февраля 2011

То, что память в машине времени выполнения доступна только для чтения, совершенно не имеет значения. Прежде чем пытаться записать косвенно в память (я предполагаю, что это чтение / запись) через p, вы должны сначала определить эту память. Конечно, если оперативная память действительно доступна только для чтения, то она не будет работать независимо от того, сколько ошибок компиляции вы исправите.

Так что вы можете иметь: main() { char amit[20] = "amit"; char *p = amit; // which is the same as &amit[0]</p> <p>// yes, you are permitted to write into amit[] like these next two lines: p[0]="s"; p[1] = '\0'; // you must terminate the string if you don't want to use strcpy( ) or its friends</p> <p>// but it's better in every way to strcpy( ) into amit[], like this: strcpy( amit, "s" );</p> <p>printf("%s",p); }

1 голос
/ 28 февраля 2011

Проблема в том, что вы объявили указатель на стек, но неясно, где предполагается хранить «amit».Вам также нужна строка в стеке, и самый простой способ сделать это - выделить для нее хранилище, изменив p с указателя на массив символов.

Измените свой код следующим образом:

main()
{
  char p[] = "amit";
  p[0]='s';
  printf("%s",p);
}
1 голос
/ 28 февраля 2011

Память, используемая строкой "amit", не имеет только для чтения.Действительно, это зависит от компилятора, и поэтому вы видите это явление.

0 голосов
/ 28 января 2016

Память, используемая для «amit», не только читаема, и это зависит от компилятора погоды, которую мы можем переписать в месте p [0] или нет. Я наблюдал то же самое в (GCC) 4.1.2. Да. Ожидаемый результат и его неопределенное поведение ...

...