I am reading C Primer Plus these days and here is the code I wrote for the programming practice No.4 in Chapter 10, finding the index of the largest number in a double-typed array. I used variable length array in order to manually specify the array size:
#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;
}
This piece of program compiles normally, using MinGW (assume the program file name is prog.c):
gcc prog.c -o prog.exe -std=c99
The program works fine when the "size" varialbe is less than 5. But when I enter 6 or larger numbers for the "size" varialbe, the program crashes during runtime.
Loosely translated, the error message is:
the memory 0x00000038 used by 0x77c1c192 could not be "written".
I tried to eliminate the use of variable length array, the program seems to work fine. But I still couldn't get where is wrong with the original one.
Size is 0 when you allocate num. You get access violation later on because you try to acces num[0] which has not been allocated.
EDIT: I propose to use dynamic memory or declare num after size is read.
Put the statment double num[size];
after taking input of size from user for size variable.
The program works fine when the "size" varialbe is less than 5.
This is the most dangerous kind of programming error -- one that appears to work fine but really does not. By writing into your array, you're immediately writing into memory that is claimed for some other purpose, because your array has no length at all. You cannot just change the size of your array by changing the size
variable after the fact.
One option is to determine size
before you declare the array. Another is to perform a dynamic allocation using new
, but you'll get into that in several chapters, I'm sure.
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);
When you first declare num array
, it's size would be zero, as this is the value of size when that line is executed, although you maybe reading the value of size again later on.
When you are creating an array, the size of the array will be zero as already pointed out by others. So, when you try to fill elements into the array, there is no memory available and it overwrites into some other memory eventually leading to a memory corruption.
You can rewrite the code as below to avoid the problem.
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]);
or
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]);
Here's a link to an informative article about C99's variable length arrays which talks about some potential problems which C99's variable length arrays can cause.
As others have suggested, using malloc() is the correct way to do this. Other than that, you can just make your array an arbitrary large size, and stop accepting input once it's full.
User contributions licensed under CC BY-SA 3.0