【发布时间】:2021-12-15 15:33:53
【问题描述】:
在 C 语言中,如果我们只访问位于分配内存中的元素,那么为指向数组的指针分配内存不足是否“合法”?还是这会引发未定义的行为?
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 ]
如果这本身不是未定义的行为,那么访问另一个不相关的对象,其内存地址恰好落在数组未分配部分的地址空间内,这可能会导致严格-混叠违规?
【问题讨论】:
-
嗯。有趣的是,clang-cl 的代码分析器会警告您的
malloc行:warning GED7FF984:“malloc”的结果被转换为“int [10]”类型的指针,这与 sizeof 操作数类型“不兼容” int' [clang-analyzer-unix.MallocSizeof]。和foo = malloc(sizeof(int[5]));的类似警告(但不是在其中使用10时)。 -
本机 MSVC 代码分析器不发出警告。但请注意,诊断的存在/不存在(甚至通过 clang)并不能(反)证明 UB。
-
我认为从技术上讲它是未定义的。考虑
int (*foo)[16]并将前12 个元素设置为某个值。通过对*foo进行操作,您将告诉编译器那里有一个int [16]对象,这意味着为它保留了64 个字节。因此编译器可能会决定使用一个不错的快速 AVX-512 指令来存储前 12 个元素。该指令还存储到最后 4 个元素,但编译器认为这没关系,因为它们的值是不确定的,所以它可以使它们成为任何它想要的东西。然后编译器正在覆盖未分配的内存。它甚至可能未映射。 -
@EricPostpischil 在 80 年代有很多大学的学生使用 C 的解释器学习 C。现在通常说 C 编译器,好像语言和编译器会是一样的:)。
-
*foo上没有操作。
标签: c malloc language-lawyer pointer-to-array