我发现了一段代码,按照我的理解它应该会因为分段错误(segmentation fault)而崩溃,但是它却毫无问题地运行。下面是相关的数据结构以及代码(其中注释位于正上方):
typedef struct {
double length;
unsigned char nPlaced;
unsigned char path[0];
}
RouteDefinition* Alloc_RouteDefinition()
{
// NB: The +nBags*sizeof.. trick "expands" the path[0] array in RouteDefinition
// to the path[nBags] array
RouteDefinition *def = NULL;
return (RouteDefinition*) malloc(sizeof(RouteDefinition) + nBags * sizeof(def->path[0]));
}
为什么这个能够工作?我了解到 sizeof char* 会根据特定体系结构解析为指针的大小,但是在解引用 NULL
指针时难道它不应该崩溃吗?
malloc()
的返回值强制转换。 - unwindsizeof
可能是编译器内部的,但您通常可以通过查看标准库的offsetof
实现来观察这种有趣且具体的语言行为:它可能会获取一个由强制转换0 / NULL指针而成的虚构对象的数据成员的地址... 这甚至比sizeof
更接近边缘,但完全合法。 - Tony Delroysizeof(def->path[0])
的定义是1
,因此返回语句可以简化为更易读的形式:return malloc(sizeof(RouteDefinition) + nBags);
。 - Klas Lindbäck