【发布时间】:2015-01-14 12:00:55
【问题描述】:
举这个人为的例子:
#include <stdlib.h>
#include <string.h>
int main (int argc, char const *argv[])
{
char *buf = malloc(8);
strcpy(buf,"Hello W");
char *last = &buf[4];
size_t u = *(size_t *)(last);
printf("0x%lx",u); // prints "0x57206f" on little endian
return 0;
}
根据我对 C 的内存管理的(相当基本的)理解,这将导致以下内存读取(假设为 64 位):
+--+--+--+--+--+--+--+--+--+--+--+--+--+
|H |e |l |l |o | |W |\0|? |? |? |? |… |
+--+--+--+--+--+--+--+--+--+--+--+--+--+
^^^^^^^^^^^^^^^^^^^^^^^
从而访问可能尚未分配给程序的内存区域并导致崩溃。 然而,这在实践中似乎工作得很好——这是定义的行为吗?
加法:
我根据此处显示的代码制作了这个示例:http://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html
【问题讨论】:
-
size_t的大小是多少?是 4 吗? -
请注意,
*(size_t *)(last);也会导致未定义的行为。存储在last中的地址不是来自size_t类型,并且很可能该地址也没有与size_t类型正确对齐。 -
printf("0x%lx",u);也有未定义的行为。long和size_t的大小可能不同。使用"0x%zx",u或"0x%lx", (long)u -
@Codor 如上所述,我假设标准 64 位平台的 sizeof(size_t)==8
标签: c