繁体   English   中英

C程序内存冲突

[英]C programme memory violation

我在下面的程序中内存是只读的,但是我仍然可以对其进行写入。

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

输出为“ smit”

由于p指向只读位置,这是预期的输出吗? 当我在GCC或Visual C ++上运行该程序时,出现分段错误,但是在Turbo C ++上却出现“ smit”。

请确认此行为...

未定义行为就是未定义行为:无论得到什么,您都不会抱怨。

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

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

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

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

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

将代码更改为此:

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

运行时计算机中的内存是只读的完全无关紧要。 在尝试通过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); }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM