-1
#include <stdio.h>
#include <stdlib.h>

int main(void)
{      
  int *arr = (int*)malloc(10);
  int i;
  for(i=0;i<100;i++)
  {
    arr[i]=i;
    printf("%d", arr[i]); 
  }
  return 0;
}

我在上面运行程序并且对 malloc 的调用将分配 10 个字节的内存,并且由于每个 int 变量占用 2 个字节,因此我可以存储 5 个 int 变量,每个变量 2 个字节,从而构成我动态分配的总共 10 个字节.

但是在调用 for-loop 时,它允许我输入值直到第 99 个索引并存储所有这些值。所以在某种程度上,如果我存储 100 个 int 值,这意味着 200 个字节的内存,而我只分配了 10 个字节。

那么这段代码的缺陷在哪里,或者 malloc 的行为如何?如果 malloc 的行为以这种方式是不确定的,那么我们如何实现正确的动态内存处理?

4

5 回答 5

2

缺陷在于您的期望。当您实际编写 100*sizeof(int) 字节时,您对编译器撒谎:“我只需要 10 个字节” 。超出分配区域的写入是未定义的行为,任何事情都可能发生,从什么都没有到您期望的崩溃。

于 2013-08-03T11:18:30.017 回答
1

如果你做愚蠢的事情,期待愚蠢的行为。

malloc通常是为了向操作系统询问操作系统喜欢的内存块(如页面),然后管理该内存。这会加速未来的 malloc,尤其是在您使用大量小尺寸的 malloc 时。它减少了相当昂贵的上下文切换的数量。

于 2013-08-03T10:56:50.217 回答
0

C 不对数组访问做任何边界检查;如果您定义一个包含 10 个元素的数组,并尝试写入a[99],编译器不会做任何事情来阻止您。行为是undefined,这意味着编译器不需要对这种情况做任何特别的事情。它可能“工作”,因为它不会崩溃,但你只是破坏了一些可能在以后引起问题的东西。

做 amalloc时,不要考虑字节,要考虑元素。如果要为 N 个整数分配空间,请编写

int *arr = malloc( N * sizeof *arr ); 

并让编译器计算出字节数。

于 2013-08-03T11:32:42.637 回答
0

首先,在大多数操作系统中,int 的大小是 4 个字节。您可以通过以下方式检查: printf("the size of int is %d\n", sizeof(int)); 当您调用 malloc 函数时,您在堆内存中分配大小。堆是为动态分配预留的。从堆中分配和释放块没有强制模式;您可以随时分配块并随时释放它。这使得在任何给定时间跟踪堆的哪些部分已分配或空闲变得更加复杂。因为您的程序很小,并且您在堆中没有冲突,您可以使用 100 以上的值运行它,它也可以运行。当您知道您在使用 malloc 做什么时,您就可以构建具有适当动态内存处理的程序。当您的代码具有不正确的 malloc 分配时,程序的行为是“未知的”。但是您可以使用 gdb 调试器来查找分段将显示的位置以及堆中的内容。

于 2013-08-03T11:16:55.803 回答
0

malloc行为与它所说的完全一样,分配 n 个字节的内存,仅此而已。您的代码可能在您的 PC 上运行,但在未分配的内存上运行是未定义的行为。

一个小记...

Int 可能不是 2 个字节,它在不同的架构/SDK 上有所不同。当你想为 n 个整数元素分配内存时,你应该使用malloc( n * sizeof( int ) ).

简而言之,可以使用该语言提供的其他工具(sizeofreallocfree等)来管理动态内存。

于 2013-08-03T11:14:40.837 回答