声明一个数组vs为它分配内存

时间:2017-10-07 04:44:14

标签: c malloc

我在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];那样声明它,还是隐含的内容呢?

2 个答案:

答案 0 :(得分:0)

为10个整数静态的数组设置内存就像这样(数据存在于内存的堆栈部分。)

int array[10];

对于动态分配,数据存在于堆上。

int *array = (int *) malloc(sizeof(int) * 10);

这是一个简单的图像,大致描述了典型程序的内存布局:

enter image description here

  

为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