【问题标题】:a C program crashes, using a double-type variable length array使用双类型可变长度数组的 C 程序崩溃
【发布时间】:2012-05-31 10:39:17
【问题描述】:

这些天我正在阅读 C Primer Plus,这是我为第 10 章中的编程练习 No.4 编写的代码,查找双类型数组中最大数字的索引。我使用可变长度数组来手动指定数组大小:

#include <stdio.h>
int findmax(const double array[], int s);
//find the index of the largest number in the array
int main(void)
{
    int size = 0; //size of the array
    int index = 0; //index of the largest number
    double num[size]; //the array holding double-type numbers

    printf("Enter the size of the array: ");
        scanf("%d", &size);
    printf("Enter %d numbers: ", size);
    for (int i = 0; i < size; i++)
        scanf("%lf", &num[i]);

    index = findmax(num, size);
    printf("The index of the max number in the array is: %d\n", index);
    return 0;
}

int findmax(const double array[], int s)
{
    int index = 0;
    double max = array[0];
    for (int i = 0; i < s; i++)
            if (array[i] > max)
            {
                max = array[i];
                index = i;
            }
    return index;
}

这段程序编译正常,使用MinGW(假设程序文件名为prog.c):

gcc prog.c -o prog.exe -std=c99

当“size”变量小于 5 时程序运行良好。但是当我为“size”变量输入 6 或更大的数字时,程序在运行时崩溃。

翻译松散,错误信息是:

the memory 0x00000038 used by 0x77c1c192 could not be "written".

我试图消除可变长度数组的使用,程序似乎工作正常。但是我还是不知道原来的哪里错了。

【问题讨论】:

    标签: c arrays floating-point double variable-length


    【解决方案1】:

    分配 num 时大小为 0。您稍后会遇到访问冲突,因为您尝试访问尚未分配的 num[0]。

    编辑:我建议在读取大小后使用动态内存或声明 num。

    【讨论】:

    • @ScarletAmaranth 谢谢 - 我错过了这是 C 的部分。从我的答案中删除
    • 谢谢。我尝试在读取大小后移动数组声明,现在程序运行良好。
    【解决方案2】:

    在用户输入尺寸变量的尺寸后,放置声明double num[size];

    【讨论】:

      【解决方案3】:

      The program works fine when the "size" varialbe is less than 5. 这是最危险的一种编程错误——看起来工作正常但实际上不行。通过写入您的数组,您会立即写入出于其他目的而声明的内存,因为您的数组根本没有长度。您不能仅仅通过事后更改 size 变量来更改数组的大小。

      一种选择是在声明数组之前确定size。另一种方法是使用new 执行动态分配,但我敢肯定,你会在几章中了解它。

      【讨论】:

      • 这确实是一个危险的错误。感谢您提供详细信息。
      • new 对于 C 来说是新的,不是 id :)
      【解决方案4】:
      int size = 0; //size of the array
          int index = 0; //index of the largest number
          double num[size]; //the array holding double-type numbers
      
          printf("Enter the size of the array: ");
              scanf("%d", &size);
      

      当您第一次声明 num array 时,它的大小将为零,因为这是执行该行时的 size 值,尽管稍后您可能会再次读取 size 的值。

      【讨论】:

      • 谢谢,我现在明白了,以后我不能再改变尺寸了。
      【解决方案5】:

      当您创建数组时,数组的大小将为零,正如其他人已经指出的那样。因此,当您尝试将元素填充到数组中时,没有可用的内存,它会覆盖到其他一些内存中,最终导致内存损坏。

      您可以如下重写代码以避免该问题。

      int size = 0; //size of the array     
      int index = 0; //index of the largest number     
      double *num = NULL; //Change it to a pointer      
      printf("Enter the size of the array: ");         
      scanf("%d", &size);     
      num = malloc(size * sizeof(double));
      if(NULL == num)
      {
        printf("Malloc Failed\n");
        return 0;
      }
      printf("Enter %d numbers: ", size);     
      for (int i = 0; i < size; i++)         
      scanf("%lf", &num[i]); 
      

      int size = 0; //size of the array     
      int index = 0; //index of the largest number     
      printf("Enter the size of the array: ");         
      scanf("%d", &size);     
      
      double num[size]; //Now, num will have proper size
      printf("Enter %d numbers: ", size);     
      for (int i = 0; i < size; i++)         
      scanf("%lf", &num[i]); 
      

      这是一篇关于 C99 的可变长度数组的内容丰富的文章 link,其中讨论了 C99 的可变长度数组可能导致的一些潜在问题。

      【讨论】:

        【解决方案6】:

        正如其他人所建议的,使用 malloc() 是执行此操作的正确方法。除此之外,您可以将数组设置为任意大的大小,一旦它满了就停止接受输入。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-12-31
          • 1970-01-01
          • 2019-03-14
          • 1970-01-01
          • 2021-07-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多