Could you explain how this works..?

I somewhat have an idea how it works. But is it really that easy to 'accidently' overwrite memory like that? That's not safe at all!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>

class myint/*don't change class*/
{

public:

    myint(int val):itsvalue(val) {}

    int getitsvalue() const { return itsvalue; }

private:

    int itsvalue;

};/*don't change class*/

int main(int argc, char** argv)
{
    int buf[1];
    myint me(123);
    int *point = &buf[0];

    std::cout << me.getitsvalue() << std::endl;
    for(int n = 0; n < 500; n++) {
	    *(point-n) = 777;
	    std::cout << me.getitsvalue() << std::endl;
    }

    return 0;
}
Last edited on
Of course it's not safe. That's why you don't do it.
To make accidental mistakes less likely, you use containers and iterators.

There isn't really much to say about your code. It overwrites the memory before the buf array, which is what was created on the stack after it.
Last edited on
This was the code given to me as an answer for one of my challenges. My answer didn't involve overwriting memory like this.

Well, thanks anyway.
Could anyone explain to me how this works?
Could anyone explain to me how this works?

- The program reserves memory.
- The 'itsvalue' variable is probably saved in a memory cell not to far from 'buf'.
- So when you overwrite cells before the array, you have a good chance to overwrite the "me" integer.
Yes, I was thinking that to myself, but how could that be?! I mean if you don't have access rights to a memory location, you cannot print it.

The only two elements in the memory space of the program if you wish are buf (say 4 bytes on some machine) and myint, which is basically an int too. In this example, myint happens to be 4 bytes down buf, and so point and (point - 1) could be dereferenced. But what about (point - 2), (point - 3), ... ?

Last edited on
Yes, I was thinking that to myself, but how could that be?! I mean if you don't have access rights to a memory location, you cannot print it.

When you try it for a location you don't have access to, you'll get a segmentation fault.

The only two elements in the memory space of the program if you wish are buf (say 4 bytes on some machine) and myint, which is basically an int too.

There's far more than that. The implementation will run other code and allocate memory for various structures before main() is run. The stack also has an initial size - this is often at least a few hundred kilobytes.
And even without that, memory is generally allocated in pages (which are usually 4 KB in size) - so if you can access one byte of a page, you can generally expect to be able to access the other 4097 bytes as well.
Of course, this heavily depends on the implementation - for C++ all this is simply undefined behavior.
Last edited on
Yes, I was thinking that to myself, but how could that be?! I mean if you don't have access rights to a memory location, you cannot print it.

When you try it for a location you don't have access to, you'll get a segmentation fault.


I agree to all of this, as for the 2nd part, you're telling me I can try doing this:


1
2
3
int * loc = (int *) rand();
// fingers crossed
cout << loc << " " << *loc << endl;


I know I'll get a sigsegv, but if I can lay my hands down on a Byte in memory with a 4KB page size, then I can expect to read 2KB up and 2KB down (on average).


Last edited on
Yeah. You can find out where the page starts by rounding down to the next multiple of 4096.
Topic archived. No new replies allowed.