简体   繁体   English

C程序内存冲突

[英]C programme memory violation

I have below programme where memory is read-only, but I am still able to write to it. 我在下面的程序中内存是只读的,但是我仍然可以对其进行写入。

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

The output is "smit" 输出为“ smit”

Is it the expected output since p points a location that is read-only? 由于p指向只读位置,这是预期的输出吗? When I run this programme on GCC or on Visual C++, I get a segmentation fault, but on Turbo C++ I get "smit". 当我在GCC或Visual C ++上运行该程序时,出现分段错误,但是在Turbo C ++上却出现“ smit”。

Please confirm this behaviour... 请确认此行为...

Undefined behavior is undefined behavior: whatever you get, you can't complain. 未定义行为就是未定义行为:无论得到什么,您都不会抱怨。

String litterals used to be in writable memory. 字符串文字曾经在可写内存中。 Older compilers have this behavior. 较早的编译器具有此行为。 Some compilers (at least older versions of gcc, it seems to have been removed in the 4.X version) have an option to get it. 一些编译器(至少是较旧的gcc版本,它似乎已在4.X版本中删除)具有选择权来获取它。 I recommand not using it excepted to help porting old applications depending on it. 我建议不要使用它,只是要根据它帮助移植旧应用程序。

Writing to a string literal gives undefined behavior, so the compiler is allowed to do anything it wants when you do that. 写入字符串文字会产生未定义的行为,因此在执行该操作时,允许编译器执行任何所需的操作。

The simple answer is that Turbo C++ compiles for real-mode, so none of the memory is protected. 简单的答案是Turbo C ++是为实模式编译的,因此没有任何存储器受到保护。 Neither the compiler nor the OS will stop you from writing anything anywhere. 编译器和操作系统都不会阻止您在任何地方编写任何内容。

The memory used by the string "amit" does not have to be read-only. 由字符串使用的内存"amit"并不一定是只读的。 Indeed, this is compiler-dependent and therefore you're seeing this phenomenon. 实际上,这是依赖于编译器的,因此您会看到这种现象。

The trouble is that you declared a pointer on the stack but it isn't clear where "amit" is supposed to be stored. 麻烦在于您在堆栈上声明了一个指针,但是尚不清楚应该在哪里存储“ amit”。 You want the string on the stack too and the easiest way to do that is to allocate the storage for it by changing p from a pointer to a character array. 您还希望字符串在堆栈上,最简单的方法是通过将p从指针更改为字符数组来为其分配存储。

Change your code to this: 将代码更改为此:

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

That the memory in the run-time machine is read-only is completely irrelevant. 运行时计算机中的内存是只读的完全无关紧要。 Before trying to write indirect into memory (which I assume is read/write) through p, you must first define that memory. 在尝试通过p间接将内存写入内存(我假设是读写)之前,必须先定义该内存。 Of course if the run-time memory is indeed read-only, well, it ain't gonna work no matter how many compile errors you fix. 当然,如果运行时内存确实是只读的,那么不管您解决了多少编译错误,它都不会起作用。

So you might have: 所以你可能有:

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