C语言 分配的空间比特定类型所需的少



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

让我们说,我做:

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

提供了一个指向int的指针,但是我没有为int分配足够的内存。为什么它能起作用呢?我甚至可以显式地将它强制转换为int,这不会影响到gcc。我知道C编译器是非常简约的,但即使我给*n赋值,它也不适合字符,比如:

*n = 300;

…然后打印出来:

printf("%d", *n);

…它工作得很好,虽然现在我最希望出现一些错误,如分割错误。

我的意思是,sizeof(char)在我的机器上是1 sizeof(int)是4。因此,3个字节被写入内存中没有正确分配的某个位置。

仅仅因为它没有离开堆栈就可以工作吗?

谁能告诉我一个地方,我可能会找到有关这些东西的启示?

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

malloc的返回值是void*,语言允许将其隐式转换为任何指针类型,在本例中是int*。编译器通常不包含检查传递给malloc的内容是否满足特定大小要求的行为,在现实世界的代码中,这可能非常困难(当编译时不知道的非常量大小传递给malloc时)。正如你所说,C编译器通常是相当简单的。有一些"静态分析"工具可以通过分析代码来找出bug,但这是与编译器完全不同的一类工具。

…它的工作非常好,虽然现在在最新的我期望一些错误,如分割错误。我的意思是,sizeof(char)在我的机器上是1 sizeof(int)是4。因此,3个字节被写入内存中没有正确分配的某个位置。

写超出已分配内存的界限是所谓的"未定义行为"。这意味着当这种情况发生时,兼容的编译器可以做任何它想做的事情。有时它会崩溃,有时它会重写程序中的其他变量,有时什么也不会发生,有时似乎没有发生,您的程序将在以后的日期崩溃。

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

仅仅因为它没有离开堆栈就可以工作吗?

堆栈与这种特殊情况无关。

谁能告诉我一个地方,我可能会找到有关这些东西的启示?

任何一本好的C书都会有这类信息,看看这里:权威C书指南和列表

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

不要依赖这个!

相关内容

  • 没有找到相关文章

最新更新