I am just trying to get Value stored at a specific memory address using two C++ codes
Code which I using to write data to memory and get its address :
#include <iostream>
using namespace std;
int main()
{
int i = 10;
cout<<&i<<endl;
cin>>i; // This is just to make sure program doesn`t end
return 0;
}
I used cin>>i; just to make sure that it doesn't end.
After getting the address of int i, put in the following code :
#include <iostream>
using namespace std;
int main()
{
// This address changes everytime and I change it everytime
// This is just one temporary address
volatile int *x = (volatile int *)0x7ffef9246e74; // [1]
int y = *x;
cout<<y<<endl;
return 0;
}
[1] : I copied this line from this page.
Program #1 keeps running while I run Program #2
On running the second code, I am getting segmentation fault (core dumped). Any help?
Your model of how modern operating systems, compilers, etc. work is wrong. When you run the program the first time, the process gets assigned a memory space. Everything within this memory space, which is a virtual memory space, gets mapped to physical memory by the processor's MMU.
When the process finished, its memory space no longer exists. The next time you start the same program, it will run in another and independent memory space. It might be mapped to different physical memory addresses and even the virtual addresses are either not the same or they are cleared to make sure that no information is leaked from former processes.
This means that when you enter the address from the first program into the second, it has no meaning there. What is worse is that the memory address from the first run is not part of the virtual memory space of the second one when you run it, hence the CPU's MMU detects an illegal access to a memory location and you get a seg-fault.
Related
From this question : function pointer :physical or virtual address
I understood that when I print the address of any variable , it prints the virtual address . But I had read in books that implied that for each process , the virtual address starts from 0 and the MMU will actually take care of the address translation.
So when I execute the program many times , i see some random addresses ? Why does this happen ? Why doesn't it start from 0 ? Is the address denoting some offset from the base address of the actual process ? If so , doesn't it mean that its the physical address ?
I am running my pc on POP os and my system is also new.
Here are the values when i print the address of my variable in each execution :
0x7ffc62f83904
0x7ffd78dee214
0x7fff2b69f6c4
0x7ffcc89680a4
0x7ffdc5cbf514
0x7ffd00540714
0x7ffd743ac3d4
0x7ffe7c5a9914
0x7ffd1ea1d214
0x7ffe21c30d64
0x7ffe885d9de4
0x7ffc5d8432e4
0x7ffe87ebff04
0x7ffc726e88d4
0x7ffef650e684
0x7fff0a62a2f4
0x7ffe89e3aed4
0x7ffd77e596f4
0x7ffcfcf76c54
0x7fff9a2cf654
0x7ffe3a8cbf84
0x7ffc4e127704
0x7ffce1a9f894
0x7ffd908828a4
0x7ffc88b0c6b4
0x7ffc2dd04804
0x7ffda3991c24
0x7fffad288da4
0x7ffd34da2994
0x7ffc3e3dcf54
0x7ffc6780b224
0x7ffee8f41554
0x7ffd369d9c54
0x7ffe5bdfca14
0x7ffc9a772454
0x7ffe03665d04
0x7ffce0eeb234
0x7ffc4fad04a4
0x7ffea8c715e4
0x7ffc6c3eb7f4
0x7ffea32a5e24
0x7ffea7729394
0x7ffdfbd2eab4
0x7fff36934134
0x7ffe9e15b1e4
0x7ffe12a07194
0x7ffc1b2fce34
0x7ffc3a82b684
0x7ffe56aad1d4
0x7ffd00d59c54
0x7fff58636474
0x7ffdc8940964
0x7ffed8146aa4
0x7ffd81794c94
0x7ffdce6ac874
0x7fff761a79c4
0x7ffe8fc95a24
0x7ffd3fb95464
0x7ffdbceeeb84
0x7ffc1582c2d4
0x7ffd47f0e8b4
0x7ffdd55b12f4
0x7ffc802a3db4
0x7ffebe9634a4
0x7ffec809acf4
0x7ffd0dfe0354
0x7ffc80eeb8d4
0x7fff1914b3b4
0x7fff3fee60d4
0x7ffccf1febf4
0x7ffdfe68c264
0x7ffd631c8184
0x7ffd814bc3c4
0x7ffc53a2d3d4
0x7fff49d96e14
0x7ffc16144e14
0x7ffecfe11904
0x7ffeaa3dc584
0x7ffcfb3a2894
0x7fff8a6a04b4
0x7ffcf0e035f4
0x7ffe060a7654
0x7ffce2a00954
0x7ffcc81980f4
0x7ffc0c706034
0x7fff172e4f34
0x7ffd62c963e4
0x7ffcf00501a4
0x7ffeec50b044
0x7ffd0bbb2be4
0x7ffff8fbebf4
0x7ffd6e127ac4
0x7fff0f2b9714
0x7ffe8b6da014
0x7ffc58f83344
0x7ffc3aa463e4
0x7fff8b28c9d4
0x7ffe1799f8a4
0x7fffe398f734
0x7fffb3056f74
Should it not contain duplicates ?
Now would it contain duplicates if i run the same program multiple times in parallel which would confirm that its a virtual address and not a physical address ?
No, virtual address do not need to start at zero and generally do not do so. Each operating system, program loader, and/or linker has some default memory layout. Typically nothing is mapped at address zero so that zero can act as a null pointer and cause faults if it is dereferenced. Commonly the stack is put somewhat high in memory but adjusted by a random offset to foil attacks that rely on fixed or known addresses. That is what is causing the variation you see.
Well the address should be the same each time you compile( 0x28fefc , as an example). No it should not start from 0 since the MMU does the translation.
Try again with this code, and see if it works :
#include<iostream>
using namespace std;
int main(){
int n;
cout << &n'
}
To see the value stored in an address try this, which is called dereferencing :
#include<iostream>
using namespace std;
int main(){
int n = 10;
cout << *(&n);
}
If the problem persists, i think is the new OS..
I've been getting a strange segmentation fault when allocating objects that have unordered_map as an atribute, the debug seems to point to it happening somewhere over at hashtable.h when allocating the map. Anyone know why this happens?
i reaches a value of 13222438 before the segmentation fault.
struct Graph{
unordered_map<int,Graph*> neighbor;
int something(){return (int)neighbor[0]++;///so it doesnt get optimized out
}
};
int main(){
std::list<Graph*> test;
for(long long i=0; i< 100000000.0d;i++ ){
test.push_back(new Graph());
}
std::cout<< "Done" <<std::endl;
return 0;
}
When I adjust your program to actually compile, and build it in 64-bit mode, it completes fine.
When I build it in 32-bit mode, it does with:
terminate called after throwing an instance of 'St9bad_alloc'
what(): std::bad_alloc
because it runs out of memory.
You are mostly running into system memory limitations.
On my system, sizeof(Graph) is 56. It will take about 5 GB of memory to create 100000000 of just the objects. Of course, there are other overheads associated with dynamic memory allocation and creating a list of pointers.
I am to able to run the program in my environment when creating 10000000 objects, 10 times less than the number you are using, but the crashes if I add another zero to the end of that number.
Not that long ago, I had an idea for some simple inter-process comunication: one process outputs an address to a pointer, I copy that to the input of another process, and that changes the original variable.
I implemented it like this:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
bool p;
cin>>p;
if(p){
int n;
n=0;
cout<<&n;
cin.get();
cin.get();
cout<<n;
}else{
int *point,n;
scanf("%p",&point);
cout<<point;
cin>>n;
*point+=n;
}
return 0;
}
I used scanf because cin complained, and wouldn't compile. I tried to run it, with two processes, but after I launched the second instance, and input the pointer's address, as outputed by the first, it froze. As I only have access to Windows, I have no idea as to whether it got a SIGSEGV, or if it did something completely diferent.
Is it just me trying to change the value of another process's variable that is crashing it, or is it something else that is stopping me?
You cannot do this that way because first process will not have access to the second process' memory address space (in common operating systems, including Windows and Linux).
Each process has its own memory, completely separate from that of other processes. A pointer value is meaningless in context of a different process, even if you manage to get it across.
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;
}
I have made following code in main()
int (*Addition)(int x, int y) = FuncAdd;
cout<<endl<<"Address of Addition is: "<<Addition<<endl;
Now every-time I execute it. I get values like this:
Address of Addition is: 01161450
Address of Addition is: 001B1450
Address of Addition is: 00F91450
and so on..
As we can see, address is different every time, though there is lower word (1450-H) common among all of them. So whats the reason behind it?
The address of the function was defined by the compiler and linker relative to the start of the program space. However the OS is free to load the program starting anywhere it desires, and due to Address Space Layout Randomization it will change with every run. It appears your OS uses a starting address that is a multiple of 0x10000.
The OS divides the memory into several partitions. If every partition starts from xxxx0000 H,
it appears that your FuncAdd() segment is allocated after 1450 H memory positions. It may vary due to change in length of other functions and other declarations, because the segments allocated previously determine the starting segment address of FuncAdd().
The reason is, the OS is allocating your program a different memory location from a flat memory model. So, FuncAdd()'s address can change each time. The previously allocated space will eventually be reclaimed/reused by the loader. If you try this in an OS such as Linux/Unix where memory model is virtual, you should always get a same value for FuncAdd()
I also added another function FuncAdd2() for illustration.
try this on a linux:
int FuncAdd (int x, int y){ return 0;}
int FuncAdd2 (int x, int y){return 0;}
typedef int (*fp)(int, int);
fp Addition[2];
int main()
{
Addition[0] = FuncAdd;
Addition[1] = FuncAdd2;
printf("\nAddress of *addition is %X " , Addition[0] );
printf("\nAddress of *addition1 is %X\n ", Addition[1]);
}
You will get this SAME (in Linux like OS)
Address of *addition is 80483E4 << This is a relative address to the proc and remains same
Address of *addition1 is 80483EE <