1

I am new to C++, but I am curious enough to dig into these strange things. I was wondering what happens when I convert a pointer to an int and realized could they indicate something. So I wrote this program to test my ideas as pointers in the same array are close enough in terms of memory location to be compared. This is the code that will explain my question clearly.

#include <iostream>
using namespace std;

int main() {
    cout << "--------------------[ Pointers ]--------------------" << endl;

    const unsigned int NSTRINGS = 9;
    string strArray[NSTRINGS] = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" };

    string *pStartArray = &strArray[0]; // Setting pStartArray pointer location to the first block of the array.

    string *pEndArray = &strArray[NSTRINGS - 1]; // Setting pEndArray pointer location to the last block of the array.

    cout << "---[ pStartArray value : " << *pStartArray << endl; // Showing the value of the pStartArray pointer (Just for safety check).
    cout << "---[ pEndArray value : " << *pEndArray << endl; // Showing the value of the pEndArray pointer (Just for safety check).

    short int blockDifferential = pEndArray - pStartArray; // Calculating the block differential of those two pointers.
    cout << "---[ Differential of the block locations that pointers are pointing to in array (pEndArray - pStartArray) : " << blockDifferential << endl;

    long long pStartIntLocation = (long long)pStartArray; // Converting the memory location (Hexadecimal) of pStartArray pointer to int (Maybe it's byte, regardless of being positive or negative). What's your opinion on this?
    cout << "---[ (long long) pStartArray current memory location to int : \"" << pStartIntLocation << "\"" << endl;

    long long pEndIntLocation = (long long)pEndArray;
    cout << "---[ (long long) pEndArray current memory location converted to int : \"" << pEndIntLocation << "\"" << endl; // Converting the memory location (Hexadecimal) of pEndArray pointer to int (Maybe it's byte, regardless of being positive or negative). What's your opinion on this?

    short int locationDifferential = pEndIntLocation - pStartIntLocation; // And subtracting the integer convetred location of pEndArray from pStartArray.
    cout << "---[ Differential of the memory locations converted to int ((long long)pStartArray - (long long)pEndArray) : " << locationDifferential << " (Bytes?)" << endl; // Seems like even after running the program multiple times, this number does not change. Something's fishy. Doesn't it seem like it's a random thing. It must be investigated.

    cout << "---[ Size of variable <string> (According to the computer that it's running) : " << sizeof(string) << " (Bytes)" << endl; // To know how much memory does a string consume. For example mine was 40.

    // Here it goes interesting. I can get the block differential of the pointers using <locationDifferential>.

    cout << "---[ Differential of the cell location (AGAIN) using the <locationDifferential> that I have calculated : " << locationDifferential/sizeof(string) << endl; // So definately <locationDifferential> was in bytes. Because I got 8 again. I just wonder is it a new discovery. LOL.

    /*

       I might look really crazy, because I can't tell it another way. It just can't happen.
       This is the last try to make it as clear as I can.

        pStrArray ]--\                  pEndArray ]--\
                      \     - 8 cell difference -     \
            Array =    | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
                       |-------- Differential ---------|
            Cell difference : 8 string cells
            String size that I considered : 32 Bytes
            data (location difference) : 8 * 32 = 256

            So if you see this, all this might make sense.
            I am excited to see what opinions you professional programmers have come up with.
            - D3F4U1T
    */

        cout << "----------------------------------------------------" << endl;

    return 0;
}

How does this exactly work? pStartIntLocation, pEndIntLocation are all in bytes? If so, why sometimes they return negative value? This is strange. Also correct me if I am wrong about any information I provided. - Best regards. - D3F4U1T.

Edit 2: Does the value that results from the conversion from pointer to a long long mean anything? Like the memory address but with the difference that this one is in bytes?

Edit 3: Seems like this is related to virtual address space. Correct me if I am wrong. Does the OS have any mechanism to number the memory as bytes. For example: Byte 1 , Byte 2 , ....

D3F4U1T
  • 11
  • 4
  • *"If so, why sometimes they return negative value?"* Try again with `unsigned long long` instead of `long long` -- if pointers and `long long` are both 8 bytes, then any pointer to the upper half of the address space will overflow when converted to a signed 8-byte integer, and the result will be negative. – cdhowie Mar 19 '20 at 20:09
  • 1
    If you choose to reinterpret the pointer as `long long` then you might get negative values because `long long` can have negative values. There isn't any kind of smart conversion happening. The value you get is basically meaningless. – François Andrieux Mar 19 '20 at 20:09
  • In general, pointers are unsigned locations, similar to a postal address (ever see a negative postal address?). Thus you should use an `unsigned` integer type, such as `unsigned long long` or `size_t`. If the value is larger than the largest positive for the data type, the signed version may turn it negative. – Thomas Matthews Mar 19 '20 at 20:39
  • Thanks for your kind answers. I just understood that I should put the value resulted from the conversion in an unsigned long long. I just wonder if those numbers mean anything? – D3F4U1T Mar 19 '20 at 20:47
  • 1
    @D3F4U1T *"wonder if those numbers mean anything?"* Yep, those are essentially positions (measured in bytes) in (normally) [virtual address space](https://en.wikipedia.org/wiki/Virtual_address_space) of your program of what those pointers point to. – HolyBlackCat Mar 19 '20 at 20:52
  • @HolyBlackCat, I guess you got what I mean. Thanks for your accurate answer. – D3F4U1T Mar 19 '20 at 20:57

1 Answers1

0

A "pointer" is an integer quantity of some length whose contents are understood to represent a memory address. (By convention, zero means NULL ... no address.)

If you typecast it into an integer, you are simply declaring to the compiler that *"no, these however-many bits should not be treated as an address ... treat them as an integer." The content of the location does not change, only the compiler's interpretation of it.

Typecasting does not change the bits – only the momentary interpretation of what they are and what they mean.

FYI: unions are another way to do a similar thing: every element of a union overlaps the others and describes various interpretations of the same area of storage. (In the Fortran language, this was called EQUIVALENCE.)

Mike Robinson
  • 8,490
  • 5
  • 28
  • 41