简体   繁体   中英

Change private member of class

Access and change value of private class member:

#include <stdio.h>

class hack_Me
{
private:
    size_t age;
public:
    size_t getAge() const
    {
        return this->age;
    }

    explicit hack_Me(size_t age):age(age) {  }

};

void change_age(hack_Me* h)
{
    *((int*)h) = 100;
}

int main(int argc, char* argv[])
{
    hack_Me h(12);
    printf("%d \n", h.getAge());
    change_age(&h);
    printf("%d \n", h.getAge());

    getchar();
    return 0;
}

It prints 100 after 12.

It works on MSVC 14.

Is this behavior undefined and/or compiler dependent?

UPDATE : Does StackOverflow give you points for downvotes?

Is this behavior undefined and/or compiler dependent?

Using int* to access a variable of type size_t is bad regardless of whether the variable is inside a class or it is by itself.

If you use

*(reinterpret_cast<size_t*>(h)) = 100;

It is not undefined behavior and it is not compiler dependent. I suspect, it won't be any different if you use:

*((size_t*)h) = 100;

Your class meets the requirements of a standard-layout struct .

From the C++11 Standard:

9 Classes

...

7 A standard-layout class is a class that:

— has no non-static data members of type non-standard-layout class (or array of such types) or reference,

— has no virtual functions (10.3) and no virtual base classes (10.1),

— has the same access control (Clause 11) for all non-static data members,

— has no non-standard-layout base classes,

— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and

— has no base classes of the same type as the first non-static data member.

8 A standard-layout struct is a standard-layout class defined with the class-key struct or the class-key class .

For standard-layout struct s, the pointer to an object can be aliased to the pointer to the first member variable.

From the C++11 Standard:

9.2 Class members

...

20 A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast , points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. end note ]

Inside the hack_Me you have size_t age; which may be smaller than int (eg under 8-bit architecture it might be that sizeof(size_t) == 1 and sizeof(int) == 2). If your compiler doesn't generate padding at an end of hack_Me, it may happen that the whole hack_Me is smaller than int and thus the *((int*)h) = 100; might overwrite more memory than only the first member of hack_Me. Change the hack to *((size_t*)h) = 100; and it will be probably OK (see other answers).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM