2

这些天我正在阅读 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

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

松散地翻译,错误信息是:

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

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

4

6 回答 6

3

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

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

于 2012-05-31T10:41:01.357 回答
1

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

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

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 的可变长度数组的内容丰富的文章的链接,其中讨论了 C99 的可变长度数组可能导致的一些潜在问题。

于 2012-05-31T11:07:44.813 回答
1

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

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

于 2012-05-31T10:44:10.060 回答
1
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时,它的大小将为零,因为这是执行该行时的大小值,尽管稍后您可能会再次读取大小的值。

于 2012-05-31T10:46:44.433 回答
1

正如其他人所建议的那样,使用 malloc() 是正确的方法。除此之外,你可以让你的数组任意大,一旦它满了就停止接受输入。

于 2012-05-31T20:21:06.040 回答
1

double num[size]; 在从用户输入尺寸变量的尺寸后放置语句 。

于 2012-05-31T10:42:41.677 回答