-->

Pointer arithmetics in C++ uses sizeof(type) incre

2020-05-08 12:41发布

问题:

I am confused by the behavior of pointer arithmetics in C++. I have an array and I want to go N elements forward from the current one. Since in C++ pointer is memory address in BYTES, it seemed logical to me that the code would be newaddr = curaddr + N * sizeof(mytype). It produced errors though; later I found that with newaddr = curaddr + N everything works correctly. Why so? Should it really be address + N instead of address + N * sizeof?

Part of my code where I noticed it (2D array with all memory allocated as one chunk):

// creating pointers to the beginning of each line
if((Content = (int **)malloc(_Height * sizeof(int *))) != NULL)
{
    // allocating a single memory chunk for the whole array
    if((Content[0] = (int *)malloc(_Width * _Height * sizeof(int))) != NULL)
    {
        // setting up line pointers' values
        int * LineAddress = Content[0];
        int Step = _Width * sizeof(int); // <-- this gives errors, just "_Width" is ok
        for(int i=0; i<_Height; ++i)
        {
            Content[i] = LineAddress; // faster than
            LineAddress += Step;      // Content[i] = Content[0] + i * Step;
        }
        // everything went ok, setting Width and Height values now
        Width = _Width;
        Height = _Height;
        // success
        return 1;
    }
    else
    {
        // insufficient memory available
        // need to delete line pointers
        free(Content);
        return 0;
    }
}
else
{
    // insufficient memory available
    return 0;
}

回答1:

Your error in reasoning is right here: "Since in C++ pointer is memory address in BYTES, [...]".

A C/C++ pointer is not a memory address in bytes. Sure, it is represented by a memory address, but you have to differentiate between a pointer type and its representation. The operation "+" is defined for a type, not for its representation. Therefore, when it is called one the type int *, it respects the semantics of this type. Therefore, + 1 on an int * type will advance the pointer as much bytes as the underlying int type representation uses.

You can of course cast your pointer like this: (int)myPointer. Now you have a numeric type (instead of a pointer type), where + 1 will work as you would expect from a numeric type. Note that after this cast, the representation stays the same, but the type changes.



回答2:

A "pointer" points to a location.

When you "increment", you want to go to the next, adjacent location.

Q: "Next" and "adjacent" depend on the size of the object you're pointing to, don't they?

Q: When you don't use "sizeof()", everything works, correct? Why? What do you think the compiler is doing for you, "behind your back"?

Q: What do you think should happen if you add your own "sizeof()"?

ON TOP OF the "everything works" scenario?



回答3:

pointers point to addresses, so incrementing the pointer p by N will point to the Nth block of memory from p.

Now, if you were using addresses instead of pointers to addresses, then it would be appropriate to add N*sizeof(type).