首页 文章

为特定类型分配所需的空间更少?

提问于
浏览
5

我对C编程比较陌生,很难理解整个内存分配问题 .

让我们说,我这样做:

int *n = malloc(sizeof(char));
// (assuming malloc doesn't return NULL of course)

这提供了指向int的指针,但是我没有为int分配足够的内存 . 为什么它会起作用呢?我甚至可以明确地将它转换为int,它不会打扰gcc . 我知道C编译器非常极简,但即使我为* n赋值,它也不适合char,如:

*n = 300;

......然后打印出来:

printf("%d", *n);

...它工作得非常好,虽然现在最迟我会发现像分段错误这样的错误 .

我的意思是,我的机器上sizeof(char)为1,sizeof(int)为4 . 因此,3个字节被写入存储器中尚未正确分配的某个位置 .

它只是因为它没有离开堆栈吗?

有人可以指点我到一个可以找到有关那些东西的启示的地方吗?

2 回答

  • 7

    它提供了指向int的指针,但是我没有为int分配足够的内存 . 为什么它会起作用呢?

    malloc的返回值是 void* ,该语言允许将其隐式转换为任何指针类型,在本例中为 int* . 编译器通常不包括检查传递给 malloc 的内容是否满足特定大小要求的行为,在实际代码中可能非常困难(当编译时未知的非常量大小传递给malloc时) . 正如你所说,C编译器通常是极简主义的 . 有一些"static analysis"工具可以分析代码以试图找到这些错误,但这是一个完全不同的工具类而不是编译器 .

    ...它工作得非常好,虽然现在最迟我会发现像分段错误这样的错误 . 我的意思是,我的机器上sizeof(char)为1,sizeof(int)为4 . 因此,3个字节被写入存储器中尚未正确分配的某个位置 .

    写入超出已分配内存的范围就是所谓的"undefined behavior" . 这意味着兼容的编译器可以在发生这种情况时执行任何操作 . 有时它会崩溃,有时它可以写入程序中的其他变量,有时什么都不会发生,有时似乎什么都不会发生,你的程序将在以后崩溃 .

    在这种特殊情况下,正在发生的事情是 malloc 的大多数实现分配最少16个字节(或更多或更少,如8或32),即使您要求更少 . 因此,当您覆盖单个分配的字节时,您正在写入"extra"内存,而该内存并未用于任何内容 . 强烈建议您不要在任何实际程序中依赖该行为 .

    它是否有效只是因为它不会离开堆栈?

    堆栈与此特定情况无关 .

    有人可以指点我到一个可以找到有关那些东西的启示的地方吗?

    任何好的C书都会有这种类型的信息,请看这里:The Definitive C Book Guide and List

  • 2

    通常,32位机器将在32位边界上分配新内存 - 它使内存访问更快 .
    所以它已经分配了一个字节,但是接下来的3字节是未使用的

    不要依赖于此!

相关问题