Most likely because how the structures are initialized. When declaring a local variable, its value is indeterminate, using that value then leads to undefined behavior.
The same goes for local structure variables. The member field values are simply undefined, so when you do e.g. data.effective &= ~CAP_TO_MASK(CAP_IPC_LOCK);
you use an indeterminate (and seemingly random) value for the operation.
You need to initialize the structure to a well know value before using it. Like
struct __user_cap_header_struct hdr = { 0 };
The above will set all fields in the structure to zero.
When you allocate with new
(which is C++ and not C!) then for structures (or classes) without default constructors all member fields are default constructed, and for integer fields this means they are zeroed. If you allocated the structures in the first example using malloc
(as that's the C way of allocating memory) then you would have the same result as the second example, as then the allocated memory would not be initialized at all.