user98188
user98188

Reputation:

What exactly do pointers store? (C++)

I know that pointers store the address of the value that they point to, but if you display the value of a pointer directly to the screen, you get a hexadecimal number. If the number is exactly what the pointer stores, then when saying

pA = pB; //both are pointers

you're copying the address. Then wouldn't there be a bigger overhead to using pointers when working with very small items like ints and bools?

Upvotes: 8

Views: 3406

Answers (8)

Elliott
Elliott

Reputation: 2623

Yes, you're right, both in terms of speed and memory.

Pointers almost always take up more bytes than your standard int and, especially, bool and char data types. On modern machines pointers typically are 8 bytes while char is almost always just 1 byte.

In this example, accessing the the char and bool from Foo requires more machine instructions than accessing from Bar:

struct Foo
{
    char * c; // single character
    bool * b; // single bool
};

struct Bar
{
    char c;
    bool b;
};

... And if we decide to make some arrays, then the size of the arrays of Foo would be 8 times larger - and the code is more spread-apart so this means you'll end up having a lot more cache misses.

#include <vector>

int main()
{
    int size = 1000000;
    std::vector<Foo> foo(size);
    std::vector<Bar> bar(size);

    return 0;
}

As dmckee pointed out, a single copy of a one-byte bool and a single copy of a pointer are just as fast:

bool num1, num2,* p1, * p2;
num1 = num2; // this takes one clock cycle
p1 = p2; // this takes another

As dmckee said, this is true when you're using a 64-bit architecture.

However, copying of arrays of ints, bools and chars can be much faster, because we can squeeze multiples of them onto each register:

#include <iostream>

int main ()
{
    const int n_elements = 100000 * sizeof(int64_t);

    bool A[n_elements];
    bool B[n_elements];

    int64_t * A_fast = (int64_t *) A;
    int64_t * B_fast = (int64_t *) B;

    const int n_quick_elements = n_elements / sizeof(int64_t);

    for (int i = 0; i < 10000; ++i)
        for (int j = 0; j < n_quick_elements; ++j)
            A_fast[j] = B_fast[j];

    return 0;
}

The STL containers and other good libraries do this sort of thing for us, using type_traits (is_trivially_copyable) and std::memcopy. Using pointers under the false guise that they're always just as fast can prevent those libraries from optimising.

Conclusion: It may seem obvious with these examples, but only use pointers/references on basic data types when you need to take/give access to the original object.

Upvotes: -1

abhinav1602
abhinav1602

Reputation: 1290

Let me start from the basics. First of all, you will have to know what variable are and how they are used.

Variables are basically memory locations(usually containing some values) and we use some identifier(i.e., variable names) to refer to that memory location and use the value present at that location.

For understanding it better, suppose we want the information from memory cells present at some location relative to the current variable. Can we use the identifier to extract information from nearby cells? No. Because the identifier(variable name) will only give the value contained in that particular cell.

But, If somehow we can get the memory address at which this variable is present then we can easily move to nearby locations and use their information as well(at runtime).

This is where pointers come into play. They are used to store the location of that variable so that we can use the additional address information whenever required.

Syntax: To store the address of a variable we can simply use & (address-of) operator.

foo = &bar 

Here foo stores the address of variable bar.

Now, what if we want to know the value present at that address?

For that, we can simply use the * (dereference) operator.

value = *foo

Now that we have to store the address of a variable, we'll be needing the memory the same way as we need in case of a variable. This means pointers are also stored in the memory the same way as other variables, so just like in case of variables, we can also store the address of a pointer into yet another pointer.

Upvotes: 0

mduvall
mduvall

Reputation: 1038

An address in memory. Points to somewhere! :-)

Upvotes: -1

Nat
Nat

Reputation: 9951

On some architectures there is an additional overhead of pointers to characters because the architecture only supports addressing words (32- or 64-bit values). A pointer to a character is therefore stored as a word address and an offset of the character within that word. De-referencing the pointer involves fetching the word and then shifting and masking it's value to extract the character.

Upvotes: 0

Steve Fallows
Steve Fallows

Reputation: 6424

As others have said, a pointer stores a memory address which is "just a number' but that is an abstraction. Depending on processor architecture it may be more than one number, for instance a base and offset that must be added to dereference the pointer. In this case the overhead is slightly higher than if the address is a single number.

Yes, there is overhead in accessing an int or a bool via a pointer vs. directly, where the processor can put the variable in a register. Pointers are usually used where the value of the indirection outweighs any overhead, i.e. traversing an array.

I've been referring to time overhead. Not sure if OP was more concerned space or time overhead.

Upvotes: 3

Niki Yoshiuchi
Niki Yoshiuchi

Reputation: 17561

The number refers to its address in memory. The size of a pointer is typically the native size of the computer's architecture so there is no additional overhead compared to any other primitive type.

Upvotes: 0

Memory addresses.

That is the locations in memory where other stuff is.

Pointers are generally the word size of the processor, so they can generally be moved around in a single instruction cycle. In short, they are fast.

Upvotes: 3

Zifre
Zifre

Reputation: 26998

A pointer is essentially just a number. It stores the address in RAM where the data is. The pointer itself is pretty small (probably the same size as an int on 32 bit architectures, long on 64 bit).

You are correct though that an int * would not save any space when working with ints. But that is not the point (no pun intended). Pointers are there so you can have references to things, not just use the things themselves.

Upvotes: 13

Related Questions