0

i know there are several threads asking a similar question but i couldn't find a solution and i'm somewhat new to c++.

I want to calculate the length of a DWORD array. So it's just an unsigned long.

DWORD offsets[] = {0x378, 0x14, 0x0};

This is my header definition of the func:

DWORD allocateAddress(DWORD, DWORD[]);

This is inside the cpp function:

DWORD Window::allocateAddress(DWORD baseAddress, DWORD offsets[])
{
    DWORD buffer;
    DWORD pointer;

    int level = 3; // Length of offset array should be calculated here.

    for (int c = 0; c < level; c++)
    {
        if (c == 0)
        {
            buffer = this->read(baseAddress); 
        }

        pointer = buffer + offsets[c];
        buffer = this->read(pointer);
    }

    return pointer;
}

This is how i would calculate the length:

sizeof(offset) / sizeof(*offset) // or sizeof(offset[0])

If i do it like this inside the allocateAddress function, i only get 4 bytes. Testing it in the main method returns 12 bytes, which is the value i want.

std::cout << sizeof(Address::offset) << std::endl;

Why am i getting the size of a 1 dimensional DWORD? =(

Dude
  • 59
  • 1
  • 5
  • If you have a fixed-size array, use `std::array`. If not, use a container like `std::vector`. Among other things, the size is securely contained for you to use. – chris May 17 '13 at 21:33
  • @chris thank you, i haven't found this thread. – Dude May 17 '13 at 21:37

2 Answers2

1

A template function can pass the size of a static array:

template <size_t COUNT>
DWORD allocateAddress(DWORD baseAddress, DWORD (&offsets)[COUNT]) {
    // now, sizeof(offsets) gives the expected size
    // as a bonus, you could also access the element count in COUNT
}

Usually, templates are inlined inside the Window class definition, in the header file (so I got rid of the Window:: scope specifier).

Christopher Oicles
  • 3,017
  • 16
  • 11
1

This is because C/C++ does not save the length of an array anywhere in memory.

The "offsets" parameter is declared as an array of undefined length. this is of course correct since you want to support any array, BUT this means that there is no way to know the size of the array at runtime.

Think of it this way: the "sizeof" keyword returns a result based on the declaration of the variable ONLY and not the actual size at runtime.

If your variable is delcared this way:

DWORD offsets[3]

Then its type is an "array of 3 DWORDs" (DWORD[3]), so sizeof will return the size in bytes of a "array of 3 DWORDs" or 12 bytes. In your case, the size of the array is implicitly defined as DWORD[3] because you initialize it with three values.

But if you declare a parameter as:

DWORD offsets[]

Its type becomes an "array of unknown length" (or DWORD[]). Since this is functionnaly identical to a constant pointer, "sizeof" will acts as if there is one element. So "sizeof" returns 1 * sizeof(DWORD) = 4.

Yves Dubois
  • 933
  • 4
  • 7
  • Worth noting that even if the parameter was `DWORD offsets[3]`, it would still decay. – chris May 17 '13 at 21:53
  • Indeed, its the *declaration* of the parameter that is important, not its current value. – Yves Dubois May 17 '13 at 22:03
  • 1
    No, this starts out right, but the end is wrong. offsets as in the function parameter DWORD offsets[] is an actual genuine pointer (and is not const in this context), so sizeof won't have anything to do with # of array elements as it doesn't see an array. sizeof( offsets) here will evaluate identically to sizeof( DWORD *) size of a pointer, not a single array element. – Avi Berger Nov 07 '22 at 16:43
  • 1
    **should be:** So "sizeof" returns 1 * sizeof(DWORD*) = 4. **(on a 32-bit platform)** – Eljay Nov 07 '22 at 16:49