int numbers*;
numbers = malloc ( sizeof(int) * 10 );
我想知道这个动态内存分配是如何的,如果我只能存储10个int
项到内存块?我可以使用数组并使用index动态存储元素。为什么上面的方法更好?
我是C的新手,这是我的第二天,我可能听起来很傻,所以请原谅我。
在这种情况下,您可以将10替换为在运行时分配的变量。这样您就可以决定需要多少内存空间。但是对于数组,您必须在声明期间指定一个整型常量。因此,您无法确定用户是否真的需要声明的那么多位置,或者更糟的是,可能还不够。
使用这样的动态分配,您可以分配一个更大的内存位置,并将第一个位置的内容复制到新的位置,以给人一种数组已根据需要增长的印象。
这有助于确保最佳的内存利用率。
malloc()
有用的主要原因是不是,因为数组的大小可以在运行时确定- C的现代版本也允许使用普通数组。有两个原因:
- 使用
malloc()
分配的对象具有灵活的生命周期;
也就是说,您可以在运行时控制何时创建和何时销毁对象。被malloc()
分配的数组从malloc()
调用时一直存在,直到相应的free()
调用;相反,声明的数组要么一直存在,直到它们声明的函数退出,要么直到程序结束。
-
malloc()
报告失败,允许程序以优雅的方式处理。
在分配请求内存失败时,malloc()
可以返回NULL
,这允许您的程序检测并处理该条件。对于声明的数组没有这样的机制——如果未能分配足够的空间,要么程序在运行时崩溃,要么完全无法加载。
与内存分配的位置不同。使用数组语法,内存是在堆栈上分配的(假设您在函数中),而malloc'ed数组/字节是在堆上分配的。
/* Allocates 4*1000 bytes on the stack (which might be a bit much depending on your system) */
int a[1000];
/* Allocates 4*1000 bytes on the heap */
int *b = malloc(1000 * sizeof(int))
堆栈分配是快速的,并且在以下情况下通常是首选:
- 需要"少量"内存
- 指向数组的指针不会从函数 返回
堆分配较慢,但有以下优点:
- 可用堆内存(通常)>>大于可用堆栈内存
- 你可以自由地传递指针到周围分配的字节,例如从函数返回它——只是记住在某个时候释放它。
第三种选择是使用静态初始化数组,如果你有一些常见的任务,总是需要一个最大大小的数组。如果可以节省数组静态消耗的内存,就避免了堆内存分配的命中,获得了传递指针的灵活性,并且避免了跟踪指针的所有权以确保内存被释放。
编辑:如果你正在使用C99(默认与gnu c编译器我认为?),你可以做可变长度的堆栈数组,如
int a = 4;
int b[a*a];
在你给的例子中
int *numbers;
numbers = malloc ( sizeof(int) * 10 );
没有明显的好处。但是,假设10是一个在运行时改变的值(例如用户输入),并且你需要从函数返回这个数组。例如
int *aFunction(size_t howMany, ...)
{
int *r = malloc(sizeof(int)*howMany);
// do something, fill the array...
return r;
}
malloc从堆中占用空间,而像
int *aFunction(size_t howMany, ...)
{
int r[howMany];
// do something, fill the array...
// you can't return r unless you make it static, but this is in general
// not good
return somethingElse;
}
将消耗堆栈,而堆栈的大小不及可用的整个堆。
存在更复杂的例子。例如,如果你必须构建一个根据运行时完成的一些计算而增长的二叉树,你基本上没有其他选择,只能使用动态内存分配。
数组大小在编译时定义,而动态分配在运行时完成。
因此,在您的情况下,您可以使用指针作为数组:numbers[5]
是有效的。
如果在编写程序时不知道数组的大小,则不应使用运行时分配。否则,您可以自由地使用数组,这可能更简单(例如,更少忘记释放内存的风险)
的例子:
- 要存储3d位置,你可能需要使用数组,因为它总是3个坐标
- 创建一个筛子来计算素数,您可能希望使用一个参数来给出最大值,从而使用动态分配来创建内存区域
数组用于静态地一次性分配内存。动态分配内存需要malloc
。int numbers[10];
这将静态分配内存,并且它将是连续内存。
如果您不知道数字的计数,则使用像count这样的变量。
int count;
int *numbers;
scanf("%d", count);
numbers = malloc ( sizeof(int) * count );
这在数组中是不可能的。
Dynamic不是指访问。动态是malloc的大小。如果你只是使用一个常量,比如在你的例子中10,它就没有比一个数组更好的了。这样做的好处是当你事先不知道它应该有多大时,例如,因为用户可以在运行时输入大小。然后你可以用一个变量来分配,比如malloc(sizeof(int) * userEnteredNumber)
。对于array,这是不可能的,因为您必须在编译时知道(最大)大小。