#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个2个字节的int变量,从而组成我的总共10个字节我动态分配。
但是在调用for循环时,它允许我输入值,甚至直到第99个索引并存储所有这些值。所以在某种程度上,如果我存储100个int值,它意味着200字节的内存,而我只分配10个字节。
那么这段代码的缺陷在哪里或者malloc的行为如何?如果malloc的行为以这种方式是非确定性的,那么我们如何实现正确的动态内存处理呢?
答案 0 :(得分:2)
缺陷符合您的期望。当你实际编写100 * sizeof(int)字节时,你骗了编译器:“我只需要10个字节”。超出分配区域的写作是未定义的行为,任何事情都可能发生,从无到有,你可能会崩溃。
答案 1 :(得分:1)
如果你做傻事,就会发现愚蠢的行为。
说malloc
通常是为了向操作系统询问操作系统喜欢的内存块(如页面),然后管理该内存。这会加速未来的mallocs,特别是如果你使用大量小尺寸的malloc。它减少了非常昂贵的上下文切换次数。
答案 2 :(得分:0)
malloc
的行为完全符合它的状态,分配n个字节的内存,仅此而已。您的代码可能在您的PC上运行,但在未分配的内存上运行是未定义的行为。
小记......
Int可能不是2个字节,它在不同的体系结构/ SDK上有所不同。如果要为n个整数元素分配内存,则应使用malloc( n * sizeof( int ) )
。
总而言之,你使用该语言提供的其他工具(sizeof
,realloc
,free
等)管理动态内存。
答案 3 :(得分:0)
首先,在大多数操作系统中,int的大小是4个字节。您可以通过以下方式检查:
printf("the size of int is %d\n", sizeof(int));
调用malloc函数时,在堆内存中分配大小。堆是动态分配的预留。从堆中分配和释放块没有强制模式;您可以随时分配一个块并随时释放它。这使得在任何给定时间跟踪堆的哪些部分被分配或释放变得更加复杂。因为您的程序很小并且堆中没有冲突,所以可以运行此程序以获得更多的值100并且它也运行。
当你知道你在做什么时使用malloc然后你用适当的动态内存处理来构建程序。当您的代码具有不正确的malloc分配时,程序的行为是“未知的”。但是您可以使用gdb调试器来查找将显示分段的位置以及堆中的内容。
答案 4 :(得分:0)
C不对数组访问进行任何边界检查;如果你定义一个包含10个元素的数组,并尝试写入a[99]
,那么编译器就不会做任何事情来阻止你。行为是 undefined ,这意味着编译器不需要特别针对这种情况做任何事情。它可以&#34;工作&#34;从某种意义上讲,它不会崩溃,但是你只是破坏了某些东西可能会在以后引起问题。
在执行malloc
时,不要考虑字节,请考虑元素。如果要为N个整数分配空间,请写
int *arr = malloc( N * sizeof *arr );
让编译器计算出字节数。