C ++ stack and heap corruption

I recently read about stack and heap corruption in C and C ++. The author of the website demonstrates stack corruption using the example below.

#include<stdio.h> 
 int main(void) 
 { 
     int b = 10; 
     int a[3]; 
     a[0] = 1; 
     a[1] = 2; 
     a[2] = 3; 

     printf(" b = %d \n",b); 
     a[3] = 12; // oops it is invalid, behaviour is undefined
     printf(" b = %d \n",b); 
     printf("address of b= %x\n",&b);
     printf("address of a[3]= %x\n",&a[3]);
     return 0; 
 }

      

I have tested the above program on Visual Studio 2010 compiler (VC ++) and it gives me a runtime error that says:

the stack around variable a is corrupted

Now my question is, is the stack corrupted for life, or is it only during the execution of the above faulty program?

Same thing, I know that deleting the same pointer twice can lead to really bad things like a bunch of corruption. The following code:

int* p=new int();
delete p;
delete p;  // oops disaster here, undefined behaviour

      

When the above code snippet executes VC ++ it shows a heap corruption error at runtime.

+3


source to share


3 answers


You have to be careful with the terminology here. Will the stack be "damaged" for the rest of your life program? It could be; it may not be. In this case, you only have corrupted data in the current stack frame, so as soon as you exit this function call, in practice, your "corruption" will go away.

But that's not quite the whole story. Since you have overwritten the variable with bytes that shouldn't be there, what effects might it have on your program? The consequences of this memory corruption can logically be passed on to other function areas or even other computers if you send this data over a network connection and the data is no longer in the expected form. (Typically, your data protocol will have security features built into it to detect and discard unexpected forms of data, but that's up to you.)

The same can be said for cumulus injury. Anytime you overwrite the bytes of something that shouldn't be overwritten, and anytime you do it with arbitrary or unknowable data, you risk potentially catastrophic consequences that could logically last long before your program's life.



Within C ++ as a language, this condition is summed up in a specific phrase: undefined behavior. It says you can't really rely on anything at all after you've messed up your memory. Once you have called UB, all bets are disabled.

The only guarantee you usually use in practice is that your OS will not allow you to directly overwrite any memory that does not belong to your program. That is, damaging the memory of other processes or the OS itself is very difficult. The memory model of modern operating systems is deliberately designed to isolate programs and prevent such damage from broken programs and / or viruses.

+6


source


This is Undefined Behavior . You cannot know what will happen if you are "banned". You are not guaranteed that your program will work well.



+7


source


C ++ as well as C has no overflow check or array overflow check. However, you can abstract, you can define an array with an overloaded index operator (operator []) where you can check the array index out of bounds and act accordingly. When you delete a pointer using delete ptr (when ptr is assigned via new), the previously allocated space is returned back to the heap of space, however, the pointer's value is the same as before. So, it's good programming practice that you should make ptr NULL after deletion, eg.

int* p=new int();
...
if (p) {
  delete p;
  p = (int *) NULL;
}
// double deletion is prevented, and ptr us not dangling any more 
if (p) {
  delete p;
  p = (int *) NULL;
}

      

However, stack or heap corruption, if it exists at all, is limited in program space, and when the program terminates, usually or abnormally, all memory locations are freed back to the operating system.

0


source







All Articles