int numbers*;
numbers = malloc ( sizeof(int) * 10 );
我想知道如果我只能将10个int
项存储到内存块中,这个动态内存分配是怎样的?我可以使用数组并使用索引动态存储元素。为什么上述方法更好?
我是C的新手,这是我的第二天,我可能听起来很愚蠢,所以请耐心等待。
答案 0 :(得分:4)
在这种情况下,您可以使用在运行时分配的变量替换10。这样你就可以决定你需要多少内存空间。但是对于数组,您必须在声明期间指定一个整数常量。因此,您无法确定用户是否确实需要所声明的位置,或者更糟糕的是,这可能还不够。
通过这样的动态分配,您可以分配更大的内存位置,并将第一个位置的内容复制到新位置,以给人一种根据需要增长阵列的印象。
这有助于确保最佳的内存利用率。
答案 1 :(得分:4)
malloc()
有用的主要原因是不是,因为数组的大小可以在运行时确定 - 现代版本的C也允许使用普通数组。有两个原因:
malloc()
分配的对象具有灵活的生命周期; 也就是说,您可以获得运行时控制何时创建对象以及何时销毁它。分配有malloc()
的数组从malloc()
调用到相应的free()
调用时存在;相比之下,声明的数组要么存在,直到它们在退出时声明它们,或者直到程序结束。
malloc()
报告失败,允许程序以优雅的方式处理它。如果未能分配所请求的内存,malloc()
可以返回NULL
,这允许您的程序检测并处理该情况。声明的数组没有这样的机制 - 如果没有分配足够的空间,程序在运行时崩溃,或者无法完全加载。
答案 2 :(得分:3)
分配内存的位置有所不同。使用数组语法,内存在堆栈上分配(假设您在函数中),而malloc的数组/字节在堆上分配。
/* 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];
答案 3 :(得分:2)
在你给出的例子中
int *numbers;
numbers = malloc ( sizeof(int) * 10 );
没有明确的好处。但是,想象10是一个在运行时更改的值(例如用户输入),并且您需要从函数返回此数组。 E.g。
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;
}
将消耗不如整个堆可用的堆栈。
存在更复杂的例子。例如。如果你必须构建一个binary tree,它根据在运行时完成的一些计算而增长,你基本上没有其他选择,只能使用动态内存分配。
答案 4 :(得分:1)
数组大小在编译时定义,而动态分配在运行时完成。
因此,在您的情况下,您可以将指针用作数组:numbers[5]
有效。
如果在编写程序时不知道数组的大小,则不能使用运行时分配。否则,您可以自由使用数组,它可能更简单(例如,忘记释放内存的风险更小)
示例:
答案 5 :(得分:1)
Array用于静态分配内存。 要动态分配内存,需要使用malloc。
e.g。 int numbers[10];
这将静态分配内存,它将是连续的内存。
如果你不知道数字的数量,那么使用像count这样的变量。
int count;
int *numbers;
scanf("%d", count);
numbers = malloc ( sizeof(int) * count );
对于数组,这是不可能的。
答案 6 :(得分:0)
动态不参考访问权限。 Dynamic是malloc的大小。如果你只使用一个常数,例如像你的例子中的10,它没有比数组更好。优点是你事先不知道它必须有多大,例如因为用户可以在运行时输入大小。然后你可以用变量分配,例如比如malloc(sizeof(int) * userEnteredNumber)
。这对于数组是不可能的,因为你必须在编译时知道(最大)大小。