使用T[]访问相邻声明的两个T类型对象是否属于C++未定义行为?——解析CppCon演讲相关案例及malloc分配数组的访问疑问
Great question—this is a nuanced topic tied to C++'s object model and the rules governing pointer arithmetic, so let’s unpack it clearly.
Why Accessing Adjacent double Objects is Undefined Behavior
First, let’s clarify the scenario Miro Kenjp was referring to: this isn’t about elements in an array (which is perfectly legal), but about two separate, adjacent double variables like this:
double a = 1.0; double b = 2.0; // This is undefined behavior! double& adjacent = *(&a + 1);
The core reason is rooted in the C++ standard’s rules for pointer arithmetic and object boundaries:
- The standard only permits pointer arithmetic (and dereferencing the resulting pointer) within the bounds of a single array object (or one past the end of the array).
- Independent variables (even if they happen to sit next to each other in memory) are not part of an array. So when you do
&a + 1, you’re creating a pointer that points outside the singledoubleobjecta—and dereferencing that pointer is undefined behavior.
Compilers rely on these rules to optimize code. For example, a compiler might assume that a pointer to a single double will never be used to access memory outside that object, so it could reorder variables, eliminate "impossible" memory accesses, or generate code that breaks if you violate this rule.
What About Your int Example?
Your code snippet:
int* twoInts = static_cast<int*>(malloc(sizeof(int) * 2)); int secondInt = twoInts[1]; // Is this UB?
This is a bit trickier because it depends on the C++ version and the type in question:
- Before C++17: Strictly speaking, this was undefined behavior.
malloconly allocates raw memory—it doesn’t create C++ objects. Even thoughintis a trivial type, the standard didn’t allow you to treat raw memory as an array ofintwithout explicitly constructing the objects (though most compilers allowed this as a common extension). - C++17 and later: The standard introduced implicit object creation for trivial types (like
int). When you access the memory viatwoInts[1], the compiler implicitly creates theintobject in that memory location. So this code is now well-defined.
It’s important to note that this is different from the independent double variables case: here, you’re intentionally allocating a block of memory to use as an array, which aligns with the standard’s rules for array-like access (once the objects are created, either explicitly or implicitly).
Key Takeaways
- Accessing a separate adjacent variable via pointer arithmetic on another variable is always undefined behavior—regardless of the type.
- Using
mallocto allocate memory for an array of trivial types is well-defined in C++17+ (thanks to implicit object creation); for non-trivial types, you’d need to use placementnewto construct the objects first.
内容的提问来源于stack exchange,提问作者匿名用户

