简体   繁体   English

分配的内存少于指定的数组指针大小

[英]Allocating less memory than the specified size of a pointer-to-array

In C, is it "legal" to under-allocate memory to a pointer-to-array if we then only access elements that fall within the allocated memory?在 C 中,如果我们只访问属于已分配内存的元素,那么将内存分配不足给数组指针是否“合法”? Or does this invoke undefined behavior?或者这是否会调用未定义的行为?

int (*foo)[ 10 ]; //Pointer to array of 10 ints
foo = malloc( sizeof( int ) * 5 ); //Under-allocation! Only enough memory for 5 ints
//Now we only ever access (*foo)[ 0 - 4 ]

If this, in and of itself, is not undefined behavior, then could accessing another, unrelated object whose memory address happens to fall within the address space of unallocated part of the array cause a strict-aliasing violation?如果这本身不是未定义的行为,那么访问另一个不相关的对象,其内存地址恰好落在数组未分配部分的地址空间内会导致严格别名违规吗?

This is undefined behavior .这是未定义的行为

foo is supposed to point to an object (or the first of an array of objects) of type int[10] . foo应该指向int[10]类型的对象(或对象数组中的第一个)。 You don't allocate that much space, so the expression *foo which has type int[10] accesses an object of that type, but doing so reads past the end of an allocated memory segment.您没有分配那么多空间,因此类型为int[10]的表达式*foo访问该类型的对象,但这样做会读取已分配内存段的末尾。

As @dbush describes in his answer , an array is defined to be a contiguously allocated non-empty set of objects of the element type (C17 6.2.5/20).正如@dbush 在他的回答中所描述的,一个数组被定义为元素类型(C17 6.2.5/20)的一组连续分配的非空对象。 Clearly, then, malloc( sizeof( int ) * 5 ) does not allocate enough space for an int[10] .显然, malloc( sizeof( int ) * 5 )没有为int[10]分配足够的空间。

But I found it difficult to formally support the last part of that answer, claiming that the size differential makes (for example) (*foo)[4] have undefined behavior.但是我发现很难正式支持该答案的最后一部分,声称大小差异使(例如) (*foo)[4]具有未定义的行为。 That conclusion seems plausible, but where does the standard actually say so?这个结论似乎是有道理的,但标准实际上在哪里这么说的?

One of the main problems here is that (dynamically) allocated objects have no declared type, only, under some circumstances, an effective type determined by how they are and have been accessed.这里的主要问题之一是(动态)分配的对象没有声明类型,只有在某些情况下,有效类型取决于它们的访问方式和访问方式。 (C17 6.5/6 and footnote 88). (C17 6.5/6 和脚注 88)。 We do know that on success, malloc(n) returns a pointer to an object of size n (C17 7.22.3.4/2), but how do we attribute undefined behavior specifically to the association with that object of an effective type describing objects of size larger than n ?我们确实知道,如果成功, malloc(n)返回一个指向大小为n的对象的指针(C17 7.22.3.4/2),但是我们如何将未定义的行为具体归因于与描述对象的有效类型的对象的关联?尺寸大于n ?

I ultimately decided that the best way to connect the dots is as follows.我最终决定连接点的最佳方法如下。 Suppose that o is an allocated object of size n , T is a complete type having sizeof(T) > n , and o is read or written via an lvalue of type T .假设o是大小为n已分配对象, Tsizeof(T) > n的完整类型,并且o是通过T类型的左值读取或写入的。 Then paragraph 6.5/6 attributes effective type T to object o , but because o 's size is insuficient we must conclude that its representation constitutes a trap representation of type T (C17 3.19.4).然后第 6.5/6 段将有效类型T归因于对象o ,但由于o的大小不足,我们必须得出结论,它的表示构成了类型T (C17 3.19.4) 的陷阱表示 Paragraph 6.2.6.1/5 then reiterates the definition of "trap representation" and gets us to where we want to go:然后第 6.2.6.1/5 段重申了“陷阱表示”的定义,并让我们到达了我们想要去的地方:

Certain object representations need not represent a value of the object type.某些对象表示不需要表示对象类型的值。 If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined.如果对象的存储值具有这样的表示形式并且被没有字符类型的左值表达式读取,则行为未定义。 If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined.如果这种表示是由没有字符类型的左值表达式修改对象的全部或任何部分的副作用产生的,则行为是未定义的。 Such a representation is called a trap representation.这种表示称为陷阱表示。

(Emphasis added.) (加了重点。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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