我有以下程序,其中内存是只读的,但我仍然可以写入它。
main()
{
char *p="amit";
p[0]="s";
printf("%s",p);
}
输出是“smit”
是p
指向只读位置的预期输出吗?当我在GCC或Visual C ++上运行这个程序时,我遇到了分段错误,但在Turbo C ++上我得到了“smit”。
请确认此行为......
答案 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中也观察到相同。是它的预期输出及其未定义的行为......