我在C中编写了一个函数,它从用户那里获取10个整数并打印出来。
void memoryallocationtest(int number)
{
// allocate space for 10 integer
char *input = malloc( 32 * sizeof(char) );
long *x = malloc( number * sizeof(long) );
char *ptr;
printf("please enter 10 integer X consecutively, -2147483648 <= X <= 2147483647)\n");
/* promts user to enter ith integer
* converts input string to long value and saves result in x
*/
for(int i = 0; i < number; i++)
{
printf( "%i. Integer:", (i + 1) );
scanf( "%s", input );
x[i] = strtol( input, &ptr, 10 );
}
free(x);
free(input);
}
这是一种有效的方法吗?
为我的char-array&#34;输入&#34;分配和释放空间是否有任何意义?或者我应该像char input[32];
那样声明它,还是隐含的内容呢?
答案 0 :(得分:0)
为10个整数静态的数组设置内存就像这样(数据存在于内存的堆栈部分。)
int array[10];
对于动态分配,数据存在于堆上。
int *array = (int *) malloc(sizeof(int) * 10);
这是一个简单的图像,大致描述了典型程序的内存布局:
为char-array“input”分配和释放空间是否有任何意义,或者我应该像char输入那样声明它[32];或者是隐含的事情呢?
动态分配的优点是您无需事先知道要从OS请求多少内存。缺点是管理动态分配的内存更加困难,而且更容易受到external fragmentation的影响。当您使用malloc时,您所描述的内容不会隐式发生。
如果您事先知道需要多少内存(确切地说整数数组的长度),则无需使用动态分配(malloc),并将数组声明为“char input [32];”完全足够了。
答案 1 :(得分:0)
继续发表评论:
虽然您对语法和正确使用内存分配函数的技术理解很好,但您提供的功能没有多大意义。局部变量的静态声明总是比动态分配内存更快(例如更高效)(如果仅仅是因为保存了函数调用开销)。
“我是否需要动态分配?”之间的选择在很大程度上取决于(1)“它是否太大而无法放入堆栈?”,以及(2)“存储值所需的生命周期是多少?” C11 Standard (draft n1570) §6.2.4 Storage durations of objects
您的函数(类型void
)不会返回任何值,也不会对int
中存储的10个x
值执行任何操作。在这方面,正如所写,没有必要动态分配任何东西。简单地声明一个字符数组和长数组将提供自动存储持续时间(例如,在声明它们的函数(例如范围)的生命周期中)。因此,更有效地实现您的功能只需声明char input[32] = "";
和long x[10] = {0};
注意:在函数中声明数组时,只保证在函数生命周期内存在数组的内存。返回时,函数堆栈(以及对该函数声明为本地的任何变量)将被销毁(例如,释放内存以供重用),以及任何尝试访问数组值(或该函数的本地变量)的任何尝试该函数返回 Undefined Behavior 中的结果。
现在无论您是否返回x
并将函数类型更改为long *
,都无需动态分配input
,因为不会返回该值。
但是,如果您确实需要返回指向x
的指针,以便您存储的值在调用函数中可用,那么您需要像您一样动态分配x
。为什么?当您为x
malloc
动态分配内存时,生命周期将从分配内存的时间延长,直到它被释放(请参阅§7.22.3内存管理函数,in上面的链接)。因此,您可以像处理一样在函数中动态分配x
,然后将函数声明为long *memoryallocationtest(int number)
和return x
,以使值可用于程序的其余部分,直到您free (x);
。
这让我想到了最后一点。您编写的函数将填充x
,然后立即释放x
。虽然很好,但在实际使用x
时,只有在您以某种有意义的方式使用free (x);
之后才会进行x
调用。
总而言之,如果input
不适合堆栈,或者您决定x
为真,则无需分配return x;
,是的,为x
提供内存的一种非常有效的方法是使用malloc
。但是,如果你只是在你的函数中使用x
,它将适合函数堆栈,(直到你达到数十万个元素,架构和编译器depdendent),然后一个简单的数组声明你只需要long
。