【问题标题】:What is the correct way to allocate memory for an array depending on a command line parameter?根据命令行参数为数组分配内存的正确方法是什么?
【发布时间】:2014-11-17 19:10:24
【问题描述】:

在编写程序时,我要求用户输入数字 N,我必须使用它来为 int 数组分配内存,处理此问题的正确方法是什么:

第一种方法:

int main() {
  int array[],n;
  scanf("%d\n",&n);
  array = malloc(n * sizeof(int));
}

或第二种方法:

int main() {
  int n;
  scanf("%d\n",&n);
  int array[n];
}

【问题讨论】:

  • 我的 C 标准知识似乎生疏了,这些尝试都编译了吗?
  • 两者都不能从命令行获取,但是第一个是非法的,因为缺少数组大小。
  • 这个例子可能过于简单了。考虑到可移植性,我是否应该总是在使用scanf()从用户那里获取 N 之前分配一些固定 N 的数组?
  • 不在 main 中,使用 c99,您可以在堆栈上分配它,并且大多数编译器会在 ansi c 中执行它,除非您处于迂腐模式......仍然使用 malloc 总是可以的。在函数中执行此操作并期望它在返回时出现,这太诱人了。

标签: c arrays memory


【解决方案1】:

任何一个都可以(尽管第一种情况需要从int array[]更改为int *array);差异取决于数组的存储位置。

在第一种情况下,数组将存储在堆中,而在第二种情况下,它将(很可能)存储在堆栈中。当它存储在堆栈上时,数组的最大大小将基于堆栈大小的限制而受到更多限制。但是,如果它存储在堆中,它可能会更大。

【讨论】:

  • 我也更喜欢第一种情况,因为它使内存的动态特性更加清晰。加在末尾的两个括号会在其他代码字中丢失。
【解决方案2】:

您的第二种方法称为可变长度数组 (VLA),仅从 c99 开始受支持。这意味着如果您希望您的代码与较旧的编译器兼容(或让老年人阅读和理解......),您可能不得不退回到更标准的第一个选项。请注意,动态分配数据需要适当的维护,其中最重要的部分是 - 完成后释放它(您不会在程序中这样做)

【讨论】:

    【解决方案3】:

    假设您打算使用int *array; 而不是int array[];(第一个不会编译)。

    始终使用第一种方法,除非您知道数组大小将非常小并且您对将要运行的平台有深入的了解。自然,问题就来了,小到什么程度才算小?

    第二种方法的主要问题是没有可移植的方法来验证 VLA(可变长度数组)分配是否成功。优点是您不必管理内存,但考虑到在内存分配失败的情况下未定义行为的风险,这几乎不是一个“优势”。

    它是在 C99 中引入的,在 C11 中成为可选。这表明委员会发现它没那么有用。此外,C11 编译器可能不支持它,您必须通过检查是否已定义 __STDC_NO_VLA__ 来执行额外的检查您的编译器是否支持它。

    int my_arr[10]; 的阵列的自动存储分配可能会失败。这是现代操作系统中一个极端且不切实际的例子,但在理论上是可能的。所以我建议在任何严肃的项目中避免使用 VLA。

    【讨论】:

      【解决方案4】:

      你确实说过你想要一个命令行参数:

        int main (int argc, char **argv)
        {
           int *array ;
           int count ;
           if (argc < 2)
             return 1 ;
           count = atoi (argv[1]) ;
           array = malloc (sizeof(int)*count) ;
      
           . . .  . . 
      
           free (array) ;
           return 0 ;
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-28
        • 2011-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-10
        相关资源
        最近更新 更多