简体   繁体   中英

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"

Is it the expected output since p points a location that is read-only? When I run this programme on GCC or on Visual C++, I get a segmentation fault, but on Turbo C++ I get "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. 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. 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. 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. 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.

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. 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中也观察到它。是的,它的预期输出及其未定义的行为...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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