Variable length arrays are not allowed. But then, I recently learned that user-defined function manipulates the original array, not its own personal copy. So I thought of creating a function that gets the desired size of the array by the user and therefore modifying the size (I also initialized the array in this function).
void fill_array(int array[], int size, int in_val);
void main(){
int n, value, list[1], ctr;
clrscr();
printf("Enter the size of the array: ");
scanf("%d", &n);
printf("Enter the value that you want all of the elements to take initially: ");
scanf("%d", &value);
printf("\nAfter scanning value, n = %d\n", n);
fill_array(list, n, value);
printf("\nAfter Function fill_array Execution");
printf("\nThe values of each element of the array is now: %d ", list[0]);
printf("%d ", list [1]);
printf("%d ", list [2]);
printf("\nn = %d\n", n);
printf("value = %d\n", value);
getch();
}
void fill_array(int array[], int size, int in_val){
int ctr;
for (ctr = 0; ctr < size; ++ctr)
array[ctr] = in_val;
printf("\nInside Function");
printf("\nn = %d\n", size);
printf("value = %d\n", in_val);
}
Here's the console / a sample run:
Enter the size of the array: 3
Enter the value that you want all of the elements to take initially: 444
After scanning value, n = 3
Inside Function
n = 3
value = 444
After Function fill_array Execution
The value of each element of the array is now: 444 444 444
n = 444
value = 444
The function did modify list. However, as you can see, it also changed the value of n. After every fill_array execution, n always equals value. Will someone please explain to me why the function is changing the value of n. I don't want the value of n to change.
Within the fill_array function you are trying to write into memory that is out of bounds for list array. Doing so will result in undefined behaviour.
From wiki article on undefined behaviour:
The behavior of some programming languages—most famously C and C++—is undefined in some cases. In the standards for these languages the semantics of certain operations is described as undefined. These cases typically represent unambiguous bugs in the code, for example indexing an array outside of its bounds.
The C Committee draft (N1570) states this about Undefined Behavior:
3.4.3
1 undefined behaviour
behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
Once an array is defined, there is no way to change its size.
A workaround for this is to use dynamic memory allocation and then use the allocated memory as if it is an array. This could look something like:
printf("Enter the size of the array: ");
if (scanf("%d", &n) != 1) exit(1);
printf("Enter the value that you want all of the elements to take initially: ");
if (scanf("%d", &value) != 1) exit(1);
int * list = malloc(n * sizeof *list); // allocate memory
fill_array(list, n, value);
// and just use it as an array
list[1] = list[0] + 42; // assuming n >= 2
...
...
free(list);
If you later on need to resize the array, you can use the function realloc
As the requirement is that "Variable lenght arrays are not allowed" the only possible soulution is to allocate an array of "big enough" size.
Then you do not pass as n the size of the array, but the number of elements.
So you just loop over the array and stop at lenght n. You need to rewrite the function fill_array to accomplish this behavior.
Why you get the output you get is because of undefined behaviour. See P.W's answer for more info on that.
Related
Im trying to make a program which says how many times a specific digit appears on a 100 numbers sequence.
Meanwhile I got this error and I can´t understand what is the solution to this. I´d appreciate if you could get me some tip or the solution.
#include <stdio.h>
int main() {
int i, m, digit, val[99], count=0;
printf("Enter a number:");
scanf("%d", &val[0]);
while (val[0] < 0) {
printf("Enter a number:");
scanf("%d", &val[0]);
}
for (i=1;i<101;i++) {
val[i]=val[0]++;
printf("%d\n", val[i]);
}
printf("Enter a digit:");
scanf("%d", &m);
while (m<0||m>9) {
printf("Enter a digit:");
scanf("%d", &m);
}
do {
digit=val[i]%10;
val[i]=val[i]/10;
if (digit==m) {
count++;
}
}while (val[i]>0);
printf("The digit %d is printed %d times in this sequence.", m, count);
}
In the for loop you step outside of the array val of which the last index is 98. Instead of hard-coding the length of the array in several places it is more convenient to use a length macro, like this:
#define LEN(anArray) (sizeof (anArray) / sizeof (anArray)[0])
...
for (i = 1; i < LEN(val); i++) {
...
Also, in the do-while loop the index i is outside of the array bounds of val. You also need to check the return value of scanf to make sure the input is valid. The last printf statement also needs a trailing newline.
Edit: Note that LEN only handles "real" arrays; arrays passed to functions are received as pointers.
You allocated only int /* ... */ val[99] (only val[0] to val[98] are available) and accessed upto val[100] because the loop condition is i<101.
This will lead to dangerous out-of-range write (undefined behaior).
Allocate enough elements like int /* ... */ val[101] or fix the loop condition not to cause out-of-range access.
Also you didn't set value of i after the for (i=1;i<101;i++) loop, so value of uninitialized element will be used in the do ... while loop. Values of uninitialized elements of non-static local variables are indeterminate and using the value invokes undefned behavior.
Set i to proper value before the loop or change the indice i to proper thing.
My cousin has a school project and we can't figure out why is the array different the second time it's printed when there is no values changing in between?
Basically you enter a number which states how many rows/columns will the matrix have, and during first loop he assigns a number to every position and prints out the random number. However, the second time we go through the matrix the numbers are different and it seems that they are copied through the matrix from bottom left corner to top right corner for some reason. It seems strange to us because we never assign a different value to a position in the array after defining it for the first time.
int i,j,n,matrica[i][j],suma=0;
srand(time(NULL));
printf("\nunesi prirodan broj N[3,20] = \n");
scanf("%d",&n);
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
matrica[i][j]=rand()%100;
printf("%d, %d = %4d ",i, j, matrica[i][j]);
if(j==n-1) {
printf("\n");
}
}
}
printf("\n");
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
printf("%d, %d = %4d ", i, j, matrica[i][j]);
if(j==n-1) {
printf("\n");
}
}
}
And here is the result of this (the code I pasted here has 2 prints, and in the image there is 3 but every time you go through the matrix after the first time it's going to be the same):
We need to use malloc to allocate the dynamic amount of memory.
After
scanf("%d",&n) // PS You should check the return value - read the manual page
Put
matrica = malloc(sizeof(int) * n * n);
And declare it as
int *matrica;
Then replace
matrica[i][j]
with
matrica[i * n + j]
And after you have finished with matrica - use free i.e.
free(matrica);
int i,j,n,matrica[i][j]
At this point I must ask, what value do you think i and j will have? Right there you're invoking undefined behaviour by referring to variables declared with automatic storage duration which you've not initialised. Anything after this point is... undefined behaviour.
Having said that, I noticed a few other parts that look strange. Which book are you reading? The reason I ask is that the people I know to be reading reputable textbooks don't have these problems, thus your textbook (or resource, whatever) mustn't be working for you...
I can't read the commentary inside of the string literals, which is a shame, since that's usually quite valuable contextual information to have in a question. Nonetheless, moving on, if this were me, I'd probably declare a pointer to an array n of int, after asking for n, like so:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t n;
printf("Enter n, please: ");
fflush(stdout);
if (scanf("%zu", &n) != 1 || n == 0 || SIZE_MAX / n < n) {
puts("Invalid input or arithmetic overflow...");
return -1;
}
int (*array)[n] = malloc(n * sizeof *array);
if (!array) {
puts("Allocation error...");
return -1;
}
/* now you can use array[0..(n-1)][0..(n-1)] as you might expect */
free(array);
}
This should work for quite high numbers, much higher than int array[n][n]; would in its place... and it gives you that option to tell the user it was an "Allocation error...", rather than just SIGSEGV, SIGILL, SIGBUS or something...
... but nothing would be more optimal than just saving the seed you use to generate the random numbers, and the user input; that's only two integers, no need for dynamic allocation. There's no point storing what rand generates, amd you realise this, right? rand can generate that output purely using register storage, the fastest memory commonly available in our processors. You won't beat it with arrays, not meaningfully, and not... just not.
I am new in c programming and I am studying arrays right now. I saw that unlike java you can't print them automatically by using Arrays.toString() method. I want to write a simple function that prints the array.
In the program it asks us the size of the array and when we write it, it asks what is the value for each element and then the program calls the displayArray() function to print the array on a single line.
For example :
Hello. What will be the size of the new array?
3
Enter the 1. element
7
Enter the 2. element
5
Enter the 3. element
1
The result should be "Your array is: 7 5 1" but instead of that I get "Your array is: 3 6356728 2" as a result. Can you help?
#include <stdio.h>
void displayArray();
int main()
{
int size;
printf("Hello. What will be the size of the new array?\n");
scanf("%d", &size);
int myarray[size];
for (int i = 0; i < size; i++)
{
printf("Enter the %d. element\n" , (i + 1));
scanf("%d", &myarray[i]);
}
displayArray(myarray[size], size);
return 0;
}
void displayArray(int myarray[], int size)
{
printf("Your array is: ");
for (int i = 0; i < size; i++)
{
printf("%d ", myarray[i]);
}
return;
}
You have a problem in the function call (which your compiler should have warned you about, read the footnote later)
displayArray(myarray[size], size);
should be
displayArray(myarray, size);
because,
Type mismatch between formal parameter and actual argument: you function expects an array (a pointer to the first element of the array, to be precise), not an element of the array.
undefined behavior. For an array defined as int myarray[size], accessing element like myarray[size] is off-by-one, as C arrays are 0-based indexing.
Footnote:
If you try to compile your code, compiler should complain about the mismatch. It can happen either
You did not turn up the compiler warning level (which is a mistake from your side)
or, you chose to ignore the warnings (which is an "offense" from your side)
It's a common mistake which beginners commit.
While calling a function in which you pass an array, you only need to specify the name of the array you want to pass.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to sum an array of numbers. The array has a length determined by an input and then the user gives the array. There were no compilation errors and I am able to run other programs. On the immediate start of running the program I am given a message that program has stopped working and that windows is searching for solution.
#include <stdio.h>
int main()
{
int sum, length, count;
int array[length];
sum=0;
scanf("%d",&length);
scanf("%d",&sum);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
When you declare your array it depends on length but you ask the user for length after.
A solution could be to ask the user for length (scanf("%d",&length);) before declaring your actual array (int array[length];).
you should move int array[length] to after scanf("%d", &length). But it is not allowed in C to declare variables after the first non-declaration (it is however possible if you compile this program as C++).
In fact, in standard C you can't have a non-const length definition for an array variable. gcc on the other hand for example allows this nevertheless.
In your case, the problem is that length has an undefined value at the declaration of int array[length];. If you are lucky, your data segment has been initialized to zero (there is no guarantee for that) but otherwise, it may be any value, including a value which leads the program to exceed your physical memory.
A more standard way of doing this is:
int *array = NULL;
scanf("%d",&length);
...
array = (int*) malloc(sizeof(int) * length);
...
free(array);
By the way, even after fixing that, you will most likely get random numbers because you never actually assign the contents of the elements of array.
Local variable are initialized to 0. Hence value of length is 0. So you array is of length. You are then reading length, say 10, from stdin and expect the array to be of length 10. This can't be. Since this is a stack variable, the size is determined in time of pre-processing and not in run time. If you want to define the array length in run time then use malloc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int sum, length, count;
int *array;
sum=0;
scanf("%d", &length);
scanf("%d",&sum);
array = (int *)malloc(sizeof(int) * length);
if (array == NULL) return 0;
memset(array, length, 0);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
Thanks.
first problem:
the length variable is being used to set the number of entries in the array[], before the variable length is set. Therefore, length will contain what ever trash happens to be on the stack when the program starts so the number of entries defined in array[] is an unknown.
This results in undefined behaviour and could lead to a seg fault event, depending on what was on the stack and what the user entered for length.
second problem:
The array array[] is never initialized so will contain what ever trash is on the stack at program startup. This means the value being printed could be anything. And the 'sum' could overflow, depending on the trash values in array[]
OP program lacks the part of data input, it's asking for sum instead of the values to sum, which is weird. The only inputs requested are also never checked (the return value of scanf must always be checked).
In C (at least C99 and optionally C11) Variable Length Arrays, like the one defined by int array[length], can be used, but the variable length here is used uninitialized and before it is even asked to the user.
Moreover, the loop where the sum is calculated stops before the last element of the array (not really a big deal in this case, considering that all those variables are uninitialized...).
A better way to perform this task could be this:
#include <stdio.h>
// helper function to read an integer from stdin
int read_int( int *value ) {
int ret = 0;
while ( (ret = scanf("%d", value)) != 1 ) {
if ( ret == EOF ) {
printf("Error: Unexpected end of input.\n");
break;
}
scanf("%*[^\n]"); // ignore the rest of the line
printf("Please, enter a number!\n");
}
return ret;
}
int main(void) {
int sum = 0,
length = 0,
count,
i;
printf("Please, enter the number of values you want to add: ");
if ( read_int(&length) == EOF )
return -1;
// Use a VLA to store the numbers
int array[length];
// input the values
for ( count = 0; count < length; ++count ) {
// please, note ^^^^^^^^ the range check
printf("Value n° %2d: ", count + 1);
if ( read_int(&array[count]) == EOF ) {
printf("Warning: You entered only %d values out of %d.\n",
count, length);
break;
}
// you can sum the values right here, without using an array...
}
// sum the values in the array
for ( i = 0; i < count; ++i ) {
// ^^^^^^^^^ sum only the inputted values
sum += array[i];
}
printf("The sum of the values is:\n%d\n", sum);
return 0;
}
int akki(int arr[],int m,int n){
int i;
for(i=0;i<m;i++){
if(arr[i]==n)
return i;
}
return 20;
}
void main(){
int i,m,n,arr[10],a;
printf("Enter size of array:");
scanf("%d",&m);
printf("Enter %d elements of array:",m);
for(i=0;i<m;i++){
scanf("%d",arr[i]);
}
printf("Enter element to be searched:");
scanf("%d",&n);
a=akki(arr,m,n);
if(a!=20)
printf("Element found at %d position",a+1);
else
printf("Element not found");
}
IT is Returning 20 or some garbage value..even if condition matches... it is returning value of i.It is linear search function where m is size of array arr and n is element to be searched...
please explain in detail..i am new in c language
thankzzz in advance
You have a problem in your code. Change
scanf("%d",arr[i]);
To
scanf("%d",&arr[i]);
This is done because scanf expects an argument of type int* but you provide argument arr[i] which is of type int. Also add a check that ends the program if user inputs a number which is greater than 10 for the first scanf.
There can be two reasons.
Case 1 [Much likely for _always_]
Simple. Because your if(arr[i]==n) condition is not met, and i<m became false. It came out of for() loop and hence, return 20.
case 2 [Less likely for _always_]
By chance, the value of n is present at the 21st location [index 20] in the input array.
Apart from the coding aspect, did you understand what's the logical purpose of this function? If not, begin with that. It searches for a specific value in an array of given length, and if no element of the array matches that value, it returns 20.
Now analyze your case, based on your input.
EDIT:
After seeing the complete code, as Mr. CoolGuy has pointed out, use
scanf("%d",&arr[i]);
Just for more reference, you can look at Chapter 7.19.6.2, paragraph 12 , %d format specifier, which goes like
... The corresponding argument shall be a pointer to signed integer.
In your code, arr[i] is of type int. What you need is a int *, i.e., &arr[i].