C程序内存违规

时间:2011-02-28 06:28:12

标签: c gcc turbo-c++

我有以下程序,其中内存是只读的,但我仍然可以写入它。

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

输出是“smit”

p指向只读位置的预期输出吗?当我在GCC或Visual C ++上运行这个程序时,我遇到了分段错误,但在Turbo C ++上我得到了“smit”。

请确认此行为......

6 个答案:

答案 0 :(得分:3)

未定义的行为是未定义的行为:无论你得到什么,你都不能抱怨。

字符串litterals曾经在可写内存中。较旧的编译器具有此行为。一些编译器(至少旧版本的gcc,似乎已经在4.X版本中被删除)有一个选项来获取它。我建议不要使用它来帮助移植旧应用程序,具体取决于它。

答案 1 :(得分:3)

写入字符串文字会产生未定义的行为,因此允许编译器在您执行此操作时执行任何操作。

简单的答案是Turbo C ++编译为实模式,因此没有任何内存受到保护。编译器和操作系统都不会阻止你在任何地方写任何东西。

答案 2 :(得分:1)

字符串"amit"使用的内存 不是只读的。实际上,这是依赖于编译器的,因此您会看到这种现象。

答案 3 :(得分:1)

麻烦的是你在堆栈上声明了一个指针但是不清楚应该存储“amit”的位置。您也希望堆栈上的字符串,最简单的方法是通过将p从指针更改为字符数组来为其分配存储空间。

将您的代码更改为:

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

答案 4 :(得分:1)

运行时机器中的内存是只读的是完全无关紧要的。在尝试通过p将间接写入内存(我假设是读/写)之前,必须首先定义该内存。当然,如果运行时内存确实是只读的,那么无论你修复了多少编译错误,它都无法工作。

所以你可能有:

main()
{
  char amit[20] = "amit";
  char *p = amit;         // which is the same as &amit[0]

// 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

// but it's better in every way to strcpy( ) into amit[], like this: strcpy( amit, "s" );

printf("%s",p); }

答案 5 :(得分:0)

用于" amit"不仅是可读的,这是编译器相关的天气,我们可以重写位置p [0]或不。我在(GCC)4.1.2中也观察到相同。是它的预期输出及其未定义的行为......