Playing with memory in C++ - c++

This is bit of a strange one...I've written a very short bit of code to allocate some memory for an integer, save a value to it and print out the memory address where it is saved:
#include <iostream>
using namespace std;
int main (void) {
int * b = new int;
*b = 12345;
cout << " -> *b = " << *b << endl;
cout << " -> b = " << b << endl;
return 0;
}
Lets say this returns the following:
-> *b = 123456
-> b = 0x7f9429c04bf0
So far as I know there is no reason why this value is not still chilling in memory as I didn't actively remove it - so, just for fun, I try and run the following:
#include <iostream>
using namespace std;
int main (void) {
int * b = reinterpret_cast <int*> (0x7f9429c04bf0);
cout << " -> *b = " << *b << endl;
cout << " -> b = " << b << endl;
return 0;
}
which throws a segfault - does anyone know why this isn't allowed? I mean...it clearly isn't a good idea and I have no plans to use it in practise but I am curious.
Cheers!
Jack

Each process has its own virtual memory space separate from other processes. When the process terminates, its memory is reclaimed by the operating system.
The reason it's throwing a segfault is because the OS is unhappy with your program trying to access memory that does not belong to it.
The whole idea behind having protected memory is to isolate processes so that they can't mess with each other's memory and cause nastiness to happen. And even if you could access random memory locations, you wouldn't really find anything interesting there. It's basically the same kind of stuff you get when accessing an uninitialized pointer.

Each Process runs in its own address space, the address ur passing to reinterpret_cast should be accessible in the address space of the current process, which it isn't as the second process has a different address space layout. Also, each iteration of even the first program will give u different addresses, which is the whole point of ASLR(Address Space Layout Randomization), that is, to randomize key parts of the process memory on each new instance. Having static addresses, as used to be the case pre-ASLR, would cause havoc, leading to easy exploitation of vulnerable programs.
Read More about ASLR: http://en.wikipedia.org/wiki/Address_space_layout_randomization
Virtual Memory:
http://en.wikipedia.org/wiki/Virtual_memory

Even if you ran both programs at once I would hope you got kicked for that, in stead of getting the right answer. The implication that you think I should be able to access another programs data by guessing addresses is scary, although if you want some history, there used to be a game called "core wars" which involved doing exactly that to try to make each other crash ...
I suppose the real answer is that this has "undefined behaviour" and you should be grateful it didn't just implode.

Most modern C++ platforms work with virtual memory provided by the underlying OS. Virtual memory is not a trivial physical form of storage you seem to believe it is. Virtual memory is just an imaginary conceptual storage that exists only as long as the process runs. It simulates "memory-like" behavior every time you access your process address space.
Your access to 0x7f9429c04bf0 is not access to physical memory address, it is access to the process virtual address space, which will be redirected to some physical location that you cannot predict.
And when your process ends, its virtual memory disappears forever. It was simulated anyway, fake in a sense. When you start another process, it gets its own virtual memory that has no connection to the old one whatsoever. In that new process access to 0x7f9429c04bf0 will lead to some other physical location you cannot predict (or, as in your case, crash, if 0x7f9429c04bf0 is not even valid).
To expect that your value is "still chilling in memory" would be rather naive. In fact, your value has never really been in any "memory" suitable for any kind of "chilling".

Related

I want to read all data stored in my RAM(word)through C++? What have I done wrong?

//Program to check content of RAM(Kernel data?)
#include <iostream>
using namespace std;
int main()
{
int *a, b;
while (a != NULL) //loop till memory end
{
a = &b;
cout << "RAM " << a << " " << *a << '\n';
b++; //next address
}
return 0;
//Output link below
}
As you can see '*a' shows output 0 at starting.
Why 'b' holds zero instead of a garbage value?
Output
A program cannot (under normal circumstances) access all the RAM in a computer.
I suggest you read up on operating systems and systems programming fundamentals.
You can start with reading about virtual memory here. I'll try to find a better link and add it.
Edit: You should also read: Virtual Memory (Wikipedia) and Virtual Address Space (Wikipedia).
Edit: Just to answer your question formally, userspace processes don't have access to all the memory in your computer, they only have access to their own virtual address space. You need to be inside the kernel to access all the physical memory ie. you need to write your own kernel or write a device driver.
As with many naive questions, the answers can be quite complicated :)
A simple answer is, not everything in your data address space (what you call "RAM") belongs to your program and is freely readable.
Unless you are in kernel mode you cannot read all physical RAM. You can only read the virtual address space allocated to your own process.

Is alocating specific memory for a void pointer undefined behaviour?

I've met a situation that I think it is undefined behavior: there is a structure that has some member and one of them is a void pointer (it is not my code and it is not public, I suppose the void pointer is to make it more generic). At some point to this pointer is allocated some char memory:
void fooTest(ThatStructure * someStrPtr) {
try {
someStrPtr->voidPointer = new char[someStrPtr->someVal + someStrPtr->someOtherVal];
} catch (std::bad_alloc$ ba) {
std::cerr << ba.what << std::endl;
}
// ...
and at some point it crashes at the allocation part (operator new) with Segmentation fault (a few times it works, there are more calls of this function, more cases). I've seen this in debug.
I also know that on Windows (my machine is using Linux) there is also a Segmentation fault at the beginning (I suppose that in the first call of the function that allocates the memory).
More, if I added a print of the values :
std::cout << someStrPtr->someVal << " " << someStrPtr->someOtherVal << std::endl;
before the try block, it runs through the end. This print I've done to see if there is some other problem regarding the structure pointer, but the values are printed and not 0 or negative.
I've seen these topics: topic1, topic2, topic3 and I am thinking that there is some UB linked to the void pointer. Can anyone help me in pointing the issue here so I can solve it, thanks?
No, that in itself is not undefined behavior. In general, when code "crashes at the allocation part", it's because something earlier messed up the heap, typically by writing past one end of an allocated block or releasing the same block more than once. In short: the bug isn't in this code.
A void pointer is a perfectly fine thing to do in C/C++ and you can usually cast from/to other types
When you get a seg-fault while initialization, this means some of the used parameters are themselves invalid or so:
Is someStrPtr valid?
is someStrPtr->someVal and someStrPtr->someotherVal valid?
Are the values printed is what you were expecting?
Also if this is a multuthreaded application, make sure that no other thread is accessing those variables (especially between your print and initialization statement). This is what is really difficult to catch

Can I read any memory value

I am just curious to know if I can read any value in memory by providing it's address (in my case random). I knew it won't work but I tried:
int e = 10;
int* p = &e;
p = 0x220202;
This won't even compile. So, is there a way to read something in my computer's memory in C++ or any other programming language.
So, is there a way to read something in my computers memory
If you refer to your computer's entire memory: No, you cannot - at least not on modern desktop/mainstream operating systems. You can only read memory from your process' address space.
Have a look at virtual memory. In a nutshell: Your pointers refer to "virtual" addresses, not real ones. Special hardware in your computer translates these addresses into real addresses. The operating system defines how the mapping has to be done. This way, each process has it's own unique address space. Whenever the OS's scheduler switches to another process, it tells the hardware to switch to the corresponding translation table. Thanks to this mechanism, you get isolation between processes, which is a very good thing: If a poorly programmed application accesses invalid memory, only the process in question will crash, whereas the rest of your system is not affected.
Think about it: Without this isolation, you would potentially need to restart your computer every time you're testing some pointer arithmetic..
You can read any value that operating system allocated to your process.
In case of your example you need to typecast an integer to a pointer before assigning it:
p = (int*) 0x220202; // now p points to address 0x220202
int value = *p; // read an integer at 0x220202 into 'value'
Note that not addresses will be accessible -- some areas are read-only, on some platforms the pointer must also be properly aligned (i.e. pointers to 32-bit integers should be aligned on 4-byte boundary).
You code will compile if you replace p = 0x220202 with p = (int *)0x220202. You will not be able to access ANY memory just by providing an address. You can access only the memory within the address space of this process. Meaning your OS will simply prevent you from accessing another exe's memory.
You must cast 0x220202 to int*
Write :
p = (int*)0x220202 ;
This will compile, but it will most likely crash when you run the program.
You will get a runtime error since this memory is outside the scope of your program
#include <iostream>
using namespace std;
int main() {
int * p = (int *) 0x220202;
int i = *p;
cout << i;
return 0;
}

Pointer or Value in my case?

bool example1()
{
long a;
a = 0;
cout << a;
a = 1;
cout << a;
a = 2;
cout << a;
//and again...again until
a = 1000000;
cout << a+1;
return true;
}
bool example2()
{
long* a = new long;//sorry for the misstake
*a = 0;
cout << *a;
*a = 1;
cout << *a;
*a = 2;
cout << *a;
//and again...again until
*a = 1000000;
cout << *a + 1;
return true;
}
Note that I do not delete a in example2(), just a newbie's questions:
1. When the two functions are executing, which one use more memories?
2. After the function return, which one make the whole program use more memories?
Thanks for your help!
UPATE: just repace long* a; with long* a = new long;
UPDATE 2: to avoid the case that we are not doing anything with a, I cout the value each time.
Original answer
It depends and there will be no difference, at the same time.
The first program is going to consume sizeof(long) bytes on the stack, and the second is going to consume sizeof(long*). Typically long* will be at least as big as a long, so you could say that the second program might use more memory (depends on the compiler and architecture).
On the other hand, stack memory is allocated with OS memory page granularity (4KB would be a good estimate), so both programs are almost guaranteed to use the same number of memory pages for the stack. In this sense, from the viewpoint of someone observing the system, memory usage is going to be identical.
But it gets better: the compiler is free to decide (depending on settings) that you are not really doing anything with these local variables, so it might decide to simply not allocate any memory at all in both cases.
And finally you have to answer the "what does the pointer point to" question (as others have said, the way the program is currently written it will almost surely crash due to accessing invalid memory when it runs).
Assuming that it does not (let's say the pointer is initialized to a valid memory address), would you count that memory as being "used"?
Update (long* a = new long edit):
Now we know that the pointer will be valid, and heap memory will be allocated for a long (but not released!). Stack allocation is the same as before, but now example2 will also use at least sizeof(long) bytes on the heap as well (in all likelihood it will use even more, but you can't tell how much because that depends on the heap allocator in use, which in turn depends on compiler settings etc).
Now from the viewpoint of someone observing the system, it is still unlikely that the two programs will exhibit different memory footprints (because the heap allocator will most likely satisfy the request for the new long in example2 from memory in a page that it has already received from the OS), but there will certainly be less free memory available in the address space of the process. So in this sense, example2 would use more memory. How much more? Depends on the overhead of the allocation which is unknown as discussed previously.
Finally, since example2 does not release the heap memory before it exits (i.e. there is a memory leak), it will continue using heap memory even after it returns while example1 will not.
There is only one way to know, which is by measuring. Since you never actually use any of the values you assign, a compiler could, under the "as-if rule" simply optimize both functions down to:
bool example1()
{
return true;
}
bool example2()
{
return true;
}
That would a perfectly valid interpretation of your code under the rules of C++. It's up to you to compile and measure it to see what actually happens.
Sigh, an edit to the question made a difference to the above. The main point still stands: you can't know unless you measure it. Now both of the functions can be optimized to:
bool example1()
{
cout << 0;
cout << 1;
cout << 2;
//and again...again until
cout << 1000001;
return true;
}
bool example2()
{
cout << 0;
cout << 1;
cout << 2;
//and again...again until
cout << 1000001;
return true;
}
example2() never allocates memory for the value referenced by pointer a. If it did, it would take slightly more memory because it would require the space required for a long as well as space for the pointer to it.
Also, no matter how many times you assign a value to a, no more memory is used.
example 2 has a problem of not allocating memory for the pointer. Pointer a initially has an unknown value which makes it to point to somewhere in memory. assigning values to this pointer corrupts the content of that somewhere.
both examples use same amount of memory. (which is 4 bytes.)

Assigning A Specific Memory Address from another program, and changing it's value

Recently I've time off of school for a few days and wanted to do a small program(s) experiment in C++ dealing with memory address.
I wanted to see is that if a currently running program (Let call it Program A) that created a pointer to an int object in the heap, can be seen by another program and be modified (Program B).
So for Program A, this is my basic code:
// Program A
#include <iostream>
using namespace std;
int main()
{
// Pointer to an int object in the heap
int *pint = new int(15);
// Display the address of the memory in heap
cout << pint << endl;
// Display the value stored in that address
cout << *pint << endl;
return 0;
}
Output for Program A:
0x641030
15
For Program B, I looked at how to assigned a specific memory address through this link:
http://www.devx.com/tips/Tip/14104
The code for Program B is:
// Program B
#include <iostream>
using namespace std;
int main()
{
// assign address 0x641030 to p
int *p = reinterpret_cast< int* > (0x641030);
cout << p << endl;
cout << *p << endl;
return 0;
}
Output for Program B:
0x641030
... "Crash"
I don't quite understand it. I was expecting a display of 15 from *p, but it did something i didn't expect.
I also tried to assign *p to a number like *p = 2000 but it crashed when I attempted that as well.
Also when I display the address of the pointers and Program A (cout << &pint;) and for Program B (cout << &p;), they both showed the same memory address.
Does anyone know what is going on exactly? I'm interested yet confused of what is happening. Also, is it possible for me to do what I am attempt in C++/C ?
** EDIT **
Sorry to not mention my platform, but I am currently using Window 7 Professional
The short answer is that different processes use completely different address spaces. Without doing a lot more work, process B can't read or write the memory from process A.
It is possible to do this, in a platform-specific way. Win32 offers functions such as WriteProcessMemory where you can directly poke values into the memory space of another process. Most operating systems offer a shared memory function, with Win32 you can use memory mapped files and Unix flavours typically have some kind of equivalent "mmap" or "shmem" feature.
I think that most operating systems are designed to make it impossible (or very difficult) to do what you are trying to do -- have one running program (or process) interfere with the contents of the address space of another running program (or process). Since you don't tell us your platform it's difficult to be categorical about this, but I suspect that the o/s is saving you from yourself. This rigid separation of processes is a safety feature on single-user machines, a safety and security feature on multi-user machines.
There are, of course, many techniques for running concurrent processes which can share memory or which exchange information by message-passing. Take some more time off school and study those!
Take a look at either Memory Mapped Files or Shared Memory.
http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx