几年前,证书发布了有关某些编译器优化指针溢出检查的建议
/* note: not the code being asked about */
#include <stdint.h>
void fn(uint32_t len) {
char buffer[BUFLEN];
if (buffer + len > buffer) { /* not defined if len > BUFLEN! */
die();
}
/* do whatever */
}
咨询了C99标准后,我现在想知道即使以下代码定义明确:
#include <stdlib.h>
#include <stdint.h>
int main() {
uint32_t *buf = malloc(sizeof(uint32_t) * 20);
*(buf+10) = 100;
return *(buf+10);
}
C99标准的相关部分似乎是6.5.6/7
,6.5.6/8
和7.20.3.3/2
。我对标准的阅读表示以下内容:
-
7.20.3.3/2
毫无迹象表明由malloc
分配的内存应考虑到数组(7.20.3.1
的CF CC_6)。 - 根据
6.5.6/7
的说法,在加法表达式中,一个不是数组元素的对象的指针与指向长度数组的第一个元素的指针相同。 -
6.5.6/8
留下了不确定的加性表达式的结果,该结果将指向一个元素以上的元素,而不是一个数组对象的最后一个元素。由于6.5.6/7
表明在此添加剂表达式中,buf
的行为应与一个长度的指针相同,因此这会使buf+10
不确定。
这是否意味着上面的第二个代码根据C99标准不确定?
从7.20.3:
如果分配成功是适当对齐的,则返回的指针可以将其分配给任何类型的对象的指针,然后用于访问此类对象或此类对象的数组 分配的空间(直到明确交易空间为止。)
(强调我的。)所以我认为您可以在" malloc会给您一个数组"部分上,一旦您剩下的就可以了。