user2812393
user2812393

Reputation: 25

Attempt to read from a specific memory address

I'm trying to learn pointers by creating a script that allows me to read the memory from a given location.

# include <iostream>

using namespace std;

int main()
{
  int *p, a=5;
  p=(int*)0x12345678;
  cout << &a << "\n";
  cout << *p << "\n";  
}

The first cout gives 0xbfe08368. The second cout results in the following error:

"segmentation fault, core dumped"

which I understand means that the data can't be read from that memory address. Why is that? Is whatever data allocated there not an int? I've also tried p = (char*)0x12345678, and float, but I still get the same result. How to make it work?

Upvotes: 0

Views: 2489

Answers (5)

Abhishek Dwivedi
Abhishek Dwivedi

Reputation: 7396

You are getting segmentation fault which is not because of int but because of you are trying to look beyond your address space.

Basically, when any program comes in the execution, the program get's address space. This is a virtual memory (or in mmu less system same as physical memory) space chunk which is the home of the application provided by the kernel.

Here when you are providing a fixed address to access you are most likely peeping outside your address space. Otherwise, if you set to read data from address space which belongs to your program you can read that wether it is int, float, char or whatever.

This is a fantastic thing not an issue. Otherwise your device will be among the least secure device on this earth.

Upvotes: 0

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158449

As far as I can tell this is undefined behavior since this requires an Lvalue-to-rvalue conversion if we first look at the draft C++ standard section 5.3.1 Unary Operators paragraph 1 says(emphasis mine):

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. [...]

so the result of *p is an lvalue but since it will be converted to an rvalue we now look at section 4.1 Lvalue-to-rvalue conversion paragraph 1 it says(emphasis mine):

[...]If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.[...]

So if 0x12345678 does not contain an int then this is undefined.

In general the operating system will not allow a process to access an address not allocated to you process and in most Unix-like systems this will cause a segmentation fault.

Upvotes: 0

syam
syam

Reputation: 15069

If you get a segfault it means that part of the address space hasn't been allocated by the system to your program (which is not the same as your program allocating memory for an object).

System-wide memory gets allocated to your program whole pages at a time (typically 4kb), and in turn malloc/new use those memory pages to allocate their own memory blocks (which the system knows nothing about).

Keywords for more information / research on your part are: virtual address space / paging.

Upvotes: 1

Mike Dunlavey
Mike Dunlavey

Reputation: 40649

Your address space is broken up into segments you can access, and segments you can't.

&a is the address of a, which is in your address space. *p is not.

Upvotes: 1

Chen
Chen

Reputation: 1180

You need to allocate a block of memory (e.g., using malloc()) before you can use that block of memory. If you access a byte that was not allocated, you'll receive SIG_SEGV (segmentation fault). If you are lucky enough that the address is inside an allocated memory block, usually there's no problem accessing it.

Upvotes: 0

Related Questions