initializing an array using a function in C - c

I am doing an assignment for class and I thought I would bug you all with a question:
So the purpose of the program is for the user to enter the size of the array and then initialize it with some data. Max size is 20. My issue is that the array crashes when the sets the size beyond 14 and tries to initialize it. So forexample, if it sets the size as 20, it accepts it, but when I try to initialize it, it crashes. I have no idea what I am doing. your help is much appreciated.
Thank you very much,
Essi
int main ()
{
int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
//I have a piece a line or two of code that asks the user for the size of the
array
printf("Let's Initialize an array of size %d!!\n", sizeOfArray);
do
{
printf("Enter array element %d : ", initCounter+1);
myArray[initCounter] = userInitArray();
initCounter++;
}while (initCounter < sizeOfArray);
}
float userInitArray()
{
float num;
scanf("%f", &num);
return num;
}

These two lines
int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
Create an empty array. So whatever you try to store in this array later on is access out of bounds and invokes undefined behavior. The fact that your program crashes on 14th call is simply luck. It could have crashed on the first one just as well.

int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
Your array is created here with a size of zero. It doesn't magically expand when you later increase sizeOfArray. You need to get the size variable set first (from your 'line or two of code' user input) then create the array based on that.
You may also want to impose some sensible upper limit on your array size so you don't blow up your stack when trying, for example, to create a one-billion-entry array :-)

You have a (variable-length) array of size zero. You need to first ask for the size, and then allocate the array. Otherwise any attempts to assign to array elements would result in undefined behaviour.

You could do :
int sizeOfArray; //size Of Array
printf("tell me the size of the array");
scanf("%d",&sizeOfArray);
float myArray[sizeOfArray]; // not a good practice
The right way to do it would be:
int sizeOfArray; //size Of Array
float *myArray;
printf("tell me the size of the array");
scanf("%d",&sizeOfArray);
myArray=malloc(sizeof(float)*sizeOfArray);
You may use the pointer as a common array then.
and call like this: myArray[3] = doSomething();
EDIT Note that since you already know the max size you could avoid doing dynamic allocations listed above:
#Define MAXSIZE 20
int main ()
{
int sizeOfArray; //size Of Array
float myArray[MAXSIZE];
printf("tell me the size of the array\n");
scanf("%d",&sizeOfArray);
printf("\nLet's Initialize an array of size %d!!\n", sizeOfArray);
do
{
printf("Enter the element at myArray[%d] : ", initCounter+1);
myArray[initCounter] = userInitArray();
initCounter++;
}while (initCounter < sizeOfArray);
}
float userInitArray()
{
float num;
scanf("%f", &num);
return num;
}
Probably this last option is what your teacher is actually looking for.

You need to read sizeOfArray before you allocate myArray dynamically like this:
float * myArray = malloc(sizeOfArray * sizeof(float));
This is allocating sizeof(float) * sizeOfArray bytes of memory on heap and assigning address of allocated memory to myArray.
This is maybe hard to understand about arrays in C, they are really just pointers into memory - in your program the array myArray is allocated statically on stack and is of size 0. You cannot add any elements to it or assign to any index, it will not grow, its forewer 0 float elements long. Best thing that can happen to your program in this case is that it will crash. Worst case, it will not crash and strange things will happen;
You really should read something about memory allocation/management in C.

I think you forget to add function prototype in the beginning of your program (before main).
And also
int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
is wrong.
As you are using variable length array (valid in C99), you can do it as
int sizeOfArray; //size Of Array
printf("Let's Initialize an array of size %d!!\n", sizeOfArray);
float myArray[sizeOfArray];

dynamic arrays are not supported in C or C++.
Change your array to:
float* myAraray;
//later when you have the size , allocate it:
myArray = (float*)malloc(arrSize * sizeof(float));

Related

C - multidimensional array memory allocation based on user input

I have seen the following declaration of two dimensional array.
int arr[][3] = { {1,2,3}, {4,5,6}};
My question is how can I allocate following multidimensional array in run time based on user input of first dimension?
#define M 10
#define N 15
int arr[][M][N]
Start by declaring a pointer suitable for accessing the array:
int (*array)[M][N];
Then allocate memory for the array based on the user input:
array = malloc(P * sizeof(*array)); // P is the value obtained from the user
Then use the pointer as if it was a 3D array:
array[x][y][z] = 42;
Don't forget to free the memory when you're done with it.
C allows variable-length arrays. So after reading the first dimension from the user, you can declare the array with that size.
int n;
printf("How big is it? ");
scanf("%d", &n);
int arr[n][M][N];

Why will this not print?

Before you feel the need to mark this as a duplicate post, please don't. I have read all the threads on pointers, arrays, and functions I could find but almost all of them are far too advanced to be of any help to me.
I'm not getting an error, however my code will not print my array. It seems the issue here is using scanf. I don't think the values entered are actually being put into the array in main(). I've tried using pointers, but then I get the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" whenever I try to use scanf to collect user inputted values to put into the array.
What I am working on is limited to declaring my array in the main() function, but all the operations are to be performed in promptData() function. Any help would be great, I'm at my wits end trying to figure this out on my own.
#import <stdio.h>
void promptData(double data[], int numElem);
int main(int argc, const char * argv[])
{
int size, i;
double array[size];
promptData(array, size);
for (i = 0; i < size; i++)
printf("%.2lf\n", array[i]);
return 0;
}
void promptData(double data[], int numElem)
{
int i;
printf("Enter integer values for size of array.\n");
scanf("%i", &numElem);
for (i = 0; i < numElem; i++)
{
printf("Enter array values.\n");
scanf("%lf", &data[i]);
}
}
Your program has undefined behaviour because variable size was not initialized and has indeterminate value.
You should at first in main ask the user to enter the size of the array then define the array itself and only after that fill it with values.
For example
int main(int argc, const char * argv[])
{
int size = 0;
printf( "Enter a positive integer value for the size of the array: ");
scanf( "%i", &size);
if ( size == 0 ) exit( 1 );
double array[size];
promptData(array, size);
//...
Also in C there is no such a directive as
#import <stdio.h>
Use instead
#include <stdio.h>
At least in ANSI C 89 and C 90, you can't give a variable as the size of an array. The size of array should be known at compile time. You should be doing something like double array[size];.
Even in C99, where you can have variable sized arrays; the variables should contain proper index values at the time you declare the array. In that case, you should read the number from stdin and then declare the array.
Also in C, all parameters are passed by value. This means every function takes a copy of the parameters in the function. If you want to modify a variable's value, you should pass a pointer to it, and then modify the pointer's dereferenced value, something like:
void change(int *x)
{
*x = 7;
}
void first(void)
{
int x = 5;
change(&x);
printf("%d\n", x);
}
Adding on to the other, correct, answer by Zenith, if you want a dynamically allocated array (like you want to be able to change its size based on user input), then your only option is to use one of the memory allocation functions like malloc().
Once you actually have the size in your main function, declare your array like this:
int *myArray = malloc(sizeof(int) * size));//note that malloc will return a NULL if it fails
//you should always check
if(myArray != null) {
//do stuff with myArray like you were. You can just use myArray[] as long as you
//make SURE that you don't go beyond 'size'
}
free(myArray);
//VERY important that every malloc() has a free() with it
Note: untested, but the idea is there.
Further, to answer your other question.
If you find yourself in a situation where you need to call a function and use things INSIDE that function to change stuff where you called it, you have only two choices in C.
You can either return the value and assign it to a variable in the calling function like this:
int result = myFunction(someVariable, anotherVariable);
//do stuff with result
Or, use pointers.
I'm not explaining pointers here, that's usually several lectures worth of information, and is one of the more difficult concepts to grasp for introductory programmers. All I can tell you is you need to learn them, but this format is not the right way to go about doing that.
You're passing size to promptData as a copy.
Thus changes to numElem inside promptData will not affect the size variable in your main. Hence size remains uninitialized, i.e. has an undefined value and therefore should not be used as a size for an array.
If you need to initialize an array with a size that's only known at run-time, you need to allocate memory for the array dynamically using malloc, for example:
double* array = malloc(size * sizeof(double));

Declaring an 2 dimensional array with size according to input

Say, I want an array of words that is of max length 20. I get the number of words to be stored from user input. What is the most memory efficient way to declare the above array?
I could do something like this, but I guess its not very memory efficient?
char wordArray[1000][20];
That is I want "1000" to varies accordingly to user's input. And I can't do this.
int main()
{
int size;
printf("Enter size: ");
scanf("%d", &size);
char wordArray[size][20];
}
Generally stack size is small and you can't allocate such a big amount of memory on stack. Doing so will result in stack overflow. You need dynamic allocation.
int size;
printf("Enter size: ");
scanf("%d", &size);
char **wordArray = malloc(size*sizeof(char *));
for(int i = 0; i < size; i++)
wordArray[i] = malloc(20);
Call free to deallocate.
But, note that this will allocate defragmented memory instead of continuous unlike as in case of 2D array. To get continuous memory allocation you can use pointer to array as
int (*wordArray)[20] = malloc(size * sizeof(*wordArray));
and access the element as wordArray[i][j].
For more detailed explanation read c-faq 16.6: How can I dynamically allocate a multidimensional array?
Nope, it is not, because you're imposing an allocation of 100000 times sizeof(char) of memory. And no, you can't do as you wrote here, because during the compile-time the size of array is unknown, so space cannot be allocated. You could do it using malloc.

i need to take size of the matrix from user

i want to create a matrix in C, but size of the matrix must be determine by user.There is my code.
int row1,column1;
printf("Please enter number of rows in first matrix: ");
scanf("%d",&row1);
printf("Please enter number of columns in first matrix: ");
scanf("%d",&column1);
int M1[row1][column1];
i get errors with row1 and column1(in the last line).What is the correct way of taking size of a matrix from an user?
You have to dynamically allocate the array as you don't know the size at compile time.
My hint: use a single array it's much simpler:
int M1[] = new int[row1 * column1];
Then address it as
M1[column + line * row1];
If you absolutely need a 2D matrix, refer to this question: How do I declare a 2d array in C++ using new?
And don't forget to delete[] properly your array.
Related: dynamic allocating array of arrays in C
First allocate an array of pointers:
M1 = (int**)malloc(row1 * sizeof(int*));
And then point each to another array.
for(i = 0; i < row1; i++)
M1[i] = (int*)malloc(column1 * sizeof(int));
In c to create matrix of user defined size you need to use dynamic allocation using malloc or alloca(). you can read this link to get information on creating arrays of user defined size in c
This is because you cannot initialize an array with array length as a variable. Declare a pointer and use malloc to dynamically allocate the array.
int row1,column1;
printf("Please enter number of rows in first matrix: ");
scanf("%d",&row1);
printf("Please enter number of columns in first matrix: ");
scanf("%d",&column1);
int **arr;
//allocate the memory
arr=malloc(sizeof(int*)*row1);
int i;
for (i=0;i<row1;i++)
*(arr+i)=malloc(sizeof(int)*column1);
//do what you want to do
//free the memory
for (i=0;i<row1;i++)
free(*(arr+i));
free(arr);

How to get count of elements in an array?

I created an array and put the value into array as follow
int *ptr_int;
int list_int[10];
int i;
for (i=0; i<10; i++)
list_int[i] = i + 1;
and I assign a value into list_int array like this
list_int[17] = 18;
When I tried to get the count of array as follow
int size = sizeof(list_int ) / sizeof( int );
printf( "The size of int is %d.\n", size);
the result is only 10.
How could I get the array room count?
the result is only 10.
That's the real size. Assigning to list_int[17] is undefined behavior, and it does not magically extend the array.
You have already defined the max size of your array as 10 with the following definition
int list_int[10];
You can not assign value to list_int[17]. Becacuse list_int[17] is out of the memory of the array list_int[10] that you have defined.
You can only assign value to the element from 0 .. 9
list_int[17] = 18;
This is undefined behavior because the array size is only 10.
Note that with the exception of variable length arrays, sizeof operator is a compile time operator. The result of sizeof(list_int ) and sizeof(int) are determined in compile time.
To implement an array with dynamic size, you need to allocate the array dynamically, you may find realloc pretty helpful.
To Create Dynamic arrays ( allocated at run time )
int n;
scanf("%d",&n); // read n from the user at run time
int* x=(int*)malloc(sizeof(int)*n); // where n is the number of elements you need to allocate
////// after that you can access the array (x) using indexer
///// reading loop
for(int i=0;i<n;i++)
scanf("%d",&x[i]);
===============================================================================
Note: if you need more dynamic data structure which can allocate memory for each entry
you can use linked lists

Resources