【发布时间】:2014-07-24 03:40:52
【问题描述】:
我进行了一些调试,发现编译器分配的内存超过了所需的内存。在我的例子中,我声明了一个整数,后跟一个字符串'name [10]'。即使我刚刚提到了 10 个,我也能够插入 10 个以上的字母。我还能够打印所有这些字符。而且我注意到限制不是10而是28。在28之后插入的字符没有显示出来。有人可以向我解释为什么会这样吗?
【问题讨论】:
-
您正在调用未定义的行为——这很糟糕。编译器分配填充空间以确保数据(整数)在内存中正确对齐(可能在一个 4 字节的倍数的地址上),以便高效地访问它。很有可能,如果你写了超过 11 个字符加上终端 null,那么你是在结构之外写的。那很糟!这是缓冲区溢出的来源(即使在分配的 10 个字节之外写入也是缓冲区溢出),并且要不惜一切代价避免。 C 不是保姆语言。它可以让你在脚下射击自己。尽量不要跛行。
-
“我注意到限制不是 10 而是 28”你是如何进行这个测量的?
-
仅仅因为您可以写入未分配给您的内存并不意味着编译器正在做一些意想不到的事情。当您未能履行与编译器/库/运行时/等协商的合同时,系统可能会或可能不会决定对此做些什么,但没有任何形式的保证......
-
@DDR 如果您需要更具体的解释,请显示您正在使用的实际代码。
-
@AndrewMedico:对齐填充不能出现在结构的开头;它发生在元素之间或结构的末端。如果结构是
struct { int i; char s[10]; };,那么结构之后通常会有 2 个字节的填充。通常不会有 28 个字节作为结构的一部分。但正如我所指出的,C 语言并不会阻止你越界编写变量——当你在编写越界时遇到麻烦取决于很多因素。通过越界写入来调用未定义的行为意味着任何事情都可能发生(包括“它几乎可以工作”!)
标签: c