Viacheslav Kondratiuk
Viacheslav Kondratiuk

Reputation: 8889

How to assign constant address to pointer at c++?

I want to check how pointer address will be changed when I'm increasing/decreasing pointer value.

My code is:

void pointers_plus_minus()
{
    char *c = (char *) 0x7fff80ccd35c;
    int *i = (int *) 0x7fff80ccd35c;

    c++;
    i++;

    cout << "char pointer" << c << endl;
    cout << "int pointer" << i << endl;
}

But this code gives me Segmentation fault (core dumped).

I understand that something wrong with address, but it's not clear what. How to fix it? I'm using 64bit Ubuntu.

Upvotes: 3

Views: 621

Answers (3)

Keith Thompson
Keith Thompson

Reputation: 263667

You asked how to assign a constant address to a pointer, but doing so (a) is horrendously non-portable, and (b) doesn't necessarily serve your purpose, which is to see the effect of incrementing a pointer.

Here's a program that may satisfy your curiosity without possibly blowing up due to undefined behavior:

#include <iostream>
int main() {
    const int len = 10;
    char char_array[len];
    int int_array[len];

    char *cp = char_array;
    for (int i = 0; i <= len; i ++) {
        std::cout << "cp = " << static_cast<void*>(cp) << "\n";
        cp ++;
    }

    std::cout << '\n';

    int *ip = int_array;
    for (int i = 0; i <= len; i ++) {
        std::cout << "ip = " << static_cast<void*>(ip) << "\n";
        ip ++;
    }
}

The output on my (64-bit) system is:

cp = 0x7fffaa5ddc30
cp = 0x7fffaa5ddc31
cp = 0x7fffaa5ddc32
cp = 0x7fffaa5ddc33
cp = 0x7fffaa5ddc34
cp = 0x7fffaa5ddc35
cp = 0x7fffaa5ddc36
cp = 0x7fffaa5ddc37
cp = 0x7fffaa5ddc38
cp = 0x7fffaa5ddc39
cp = 0x7fffaa5ddc3a

ip = 0x7fffaa5ddc00
ip = 0x7fffaa5ddc04
ip = 0x7fffaa5ddc08
ip = 0x7fffaa5ddc0c
ip = 0x7fffaa5ddc10
ip = 0x7fffaa5ddc14
ip = 0x7fffaa5ddc18
ip = 0x7fffaa5ddc1c
ip = 0x7fffaa5ddc20
ip = 0x7fffaa5ddc24
ip = 0x7fffaa5ddc28

Some notes on this:

The pointer increments are valid because each pointer points to an element of an array of the proper type, or just past the end of it, at all times. (You're allowed to construct a pointer just past the end of an array; you're not allowed to dereference such a pointer.)

The output produced when print a pointer of type void* is implementation-defined. On my system, it happens to be a hexadecimal representation of the pointer value, interpreted as if it were an integer -- which is probably the most common way it's done.

You can see that the char* pointer appears to be incremented by 1 each time, and the int* pointer by 4. On my system (and probably yours), pointers are stored as byte addresses. Pointer arithmetic is defined in units of the pointed-to type, not in terms of bytes. Incrementing an int* pointer causes it to point to a memory location sizeof (int) bytes after the previous location -- in this case, 4 bytes. All pointer arithmetic is defined this way; ptr2 - ptr1 gives you the number of elements (of whatever type ptr1 and ptr2 point to) between the two addresses.

The specific values printed tell you something about how memory addresses are managed on your system. The mapping between pointers and integers will generally reflect the system's memory model. That model is largely implementation-specific.

Upvotes: 5

Luchian Grigore
Luchian Grigore

Reputation: 258698

You can't operate on pointers like they are integers (well, not outside well-defined contexts).

You're only allowed to do c++ and i++ if the pointers point inside an array which you own.

Oops, I think this is actually well-defined because 1 element is treated as an array of 1, and you're allowed to go past the end of an array by one element. Reading from that pointer is still undefined though.

Regardless, although undefined, the crash is probably because cout << c attempts to print out a string, not a pointer. Cast it to void*:

cout << "char pointer" << static_cast<void*>(c) << endl;

Although this will satisfy your curiosity, which is good, it's still undefined and shouldn't do it.

Upvotes: 9

Jared Beekman
Jared Beekman

Reputation: 320

Seg faults, my favorite error messages next to stack overflows, are when you've tried to write to an illegal memory space. That said, how can you guarantee that when your program has been loaded into memory that your stack/heap space falls within the area you are trying to reserve, and more so why would you even want to do this? This is something that can probably be done in Assembly since you have much lower access to the hardware, but I seriously doubt it can be done (or should be done if you can) in C.

Upvotes: -2

Related Questions