My C program outputs undesired array values [closed] - c

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 7 years ago.
Improve this question
I've been tasked to code a program that processes a simple 1D array to return its element values, but the compiler has been behaving strangely; outputting more values than I have array elements.. It's also not being fully compliant with one of my statements (one that prints a new line character every 8 elements) and not assigning the largest value to my variable. I think that the other two problems will go away once the first problem is fixed, however.
Here is my brief:
Design, code and test a program that:
Fills a 20 element array (marks) with random numbers between 0 and 100.
Prints the numbers out 8 to a line
Prints out the biggest number, the smallest number and the average of the numbers
And here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
srand(time(NULL));
int marks[20];
int i = 0;
int sum = 0;
int min;
int max;
for(i;i<=sizeof(marks);i ++){
marks[i] = rand() % 100;
sum += marks[i];
if(i % 8 == 0){
printf("\n");
}
printf("%d ", marks[i]);
if(marks[i]>max){
max = marks[i];
}
else if(marks[i]<min){
min = marks[i];
}
}
printf("\n\nThe minimum value is: %d", min);
printf("\nThe maximum value is: %d", max);
printf("\n\nThe average value is: %d", sum / sizeof(marks));
return 0;
}
Please can someone help me get the correct output?

sizeof() function returns the byte length of the array, so this code "thinks" your array is 20 * whatever byte size ints are on your machine. You will want to just use i < 20 in the loop or go
for (i;i<sizeof(marks)/sizeof(int); i ++) { ...
Note that you probably do not want the <= operator in the for loop, since arrays are 0 indexed, thus marks[20] is actually one beyond the array.

There are two problem I can see that will invoke undefined behavior in your code.
By saying for(i;i<=sizeof(marks);i ++), you're out of bounds.
int min; int max; are not initialized and you're attempting to use it.
to solve this.
Change the for loop condition to for(i; i< 20; i++). Better to use a preprocessor construct like #define SIZ 20 and then make use of it accross your code to make it consistent and robust.
Initialize your local variables. max should be INT_MIN, and min can be INT_MAX. (see limits.h for reference).
To clarify more on point 2, max and min are automatic local variables, and in case not initialized explicitly, it contains indeterminate values.
C11, chapter §6.7.9,
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate.
and then, directly from the Aneex J, §J.2, Undefined behaviour,
The value of an object with automatic storage duration is used while it is
indeterminate.

if(marks[i]>max){
max = marks[i];
}
else if(marks[i]<min){
min = marks[i];
}
min and max are not initialized here. Make sure to set your compiler warnings at the highest level, so you get a warning message when you forget to initialize variables.
for(i;i<=sizeof(marks);i ++){
This doesn't make sense. Replace sizeof(marks) with the number of times you want to loop, and use < instead of <=.
For example:
const int num_marks = 20; // or use #define
int marks[num_marks];
for(i = 0; i < num_marks; i++) {}

Related

Declaring Array in C with variable length [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
This block of code gives me the fibonacci numbers
#include <stdio.h>
int main()
{
int n; //integer overflow error for n > 47
printf("How many Fibonacci numbers?\n");
scanf("%d", &n);
int fibs[n];
fibs[0] = 0;
fibs[1] = 1;
printf("%d ", fibs[0]);
printf("%d ", fibs[1]);
for(int i = 2; i < n; i++)
{
fibs[i] = fibs[i - 2] + fibs[i - 1];
printf("%d ", fibs[i]);
}
return 0;
//gives 0 1 1 2 3 5 8 13 21 34 for n = 10
}
But this gives me the wrong output but no errors
#include <stdio.h>
int main()
{
int n, fibs[n];//change
printf("How many Fibonacci numbers?\n");
scanf("%d", &n);
fibs[0] = 0;
fibs[1] = 1;
printf("%d ", fibs[0]);
printf("%d ", fibs[1]);
for(int i = 2; i < n; i++)
{
fibs[i] = fibs[i - 2] + fibs[i - 1];
printf("%d ", fibs[i]);
}
return 0;
//gives 0 1 for n = 10
}
I know it definitely has something to do with the array and its size not being defined but I'm having trouble understanding what exactly is the problem.
Could someone explain what is going on here?
int n, fibs[n]; attempts to define an array using n for the length, but n has not been initialized, so its value is not determined. Common consequences include:
The definition behaves as if n has some small value, possibly zero, and then the following code attempts to store values in the array but overruns the memory reserved for it and thus destroys other data needed by the program.
The definition behaves as if n has some large value, causing the stack to overflow and the program to be terminated.
For example, storing 0 to to fibs[0] or 1 to fibs[1] might write to the memory reserved for n. Then the for loop terminates without executing any iterations because the test i < n is false.
The one big thing that I see in your code is the line int n, fibs[n];. The variable n is located on the stack since it's a local variable. That means that it's value can literally be anything before it's initialized. And since you are declaring an array using that value, the array has a random, unknown length. If it works, then that is purely coincidence. This is why your first code version works because the array is declared AFTER the scanf which initializes n. I think a better way of creating an array with a variable number of array elements is to use malloc instead...
int n, *fibs;
printf("How many Fibinocci numbers?\n");
scanf("%d", &n);
fibs = malloc(sizeof(int) * n);
if (fibs == NULL)
{
fprintf(stderr, "Unable to allocate sufficient memory for operation.\n");
exit(1);
}
Then you can use array indices fibs[0], fibs[1], etc... to access different locations in the block of memory.
Why does this work? Because int fibs[n] is LIKE a pointer to a block of memory. Technically, they are not the same, but you can generally use a pointer to a block of memory as an array. This will only work with single dimensional arrays because the compiler has no idea how many columns there are. But to work around that, you can compute that manually like this (i is the row, j is the column):
array[i * columns + j];

Summing an Array of Numbers but Receiving Error when Run [closed]

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;
}

Compare a single integer against an array of integers in C? [closed]

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
How does one compare a single integer to an array of ten integers to find if the single integer is contained within the array using C language? My apologies if original question was unclear, while swipe is equal to any number within the array I want to output PORTD=0b10000000. Thank you!
short a[10]={10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; //Array of accepted passwords.
short array[10];
int i;
for(i=0; i<10; i++){
array[i]=a[i];
}
srand(clock());
while(1){
int swipe=rand() % 20; /* Simulated code read from card swipe, in this
* instance we used a random number between
* 1 and 20.*/
for(i=0; i<10; i++){
if(swipe == array[i]) {
PORTD=0b10000000;
} else {
PORTD=0b00001000;
} //If swiped code evaluates as one of the approved codes then set PORTD RD7 as high.
}
char Master=PORTDbits.RD7;
This seems to have solved it...thanks for all of your help!
for(i=0; i<10; i++){
if(swipe == array[i]) {
PORTD=0b10000000;
break;
} else {
PORTD=0b00001000;
}
}
You need to test your swipe value against ALL ten values in your array of accepted passwords.
e.g. like below
for(i=0; i<10; i++)
if(swipe == array[i]) {
set a true flag (and maybe exit the for loop)
}
Depending on the flag, set the output
In addition to #kaylum's answer...
Because you are calling rand() in a loop, you need to call srand() first before entering the loop,
srand(clock());//for example
while(1){
LATD=0x00;
int swipe=rand() % 20;
...
If you do not, the random numbers you get will be the same sequence of values every time you execute.
Additionally, if i is not reinitialized before being used to compare, it is == 10. It needs to be reset before using as your array index...
Also, in your code, it appears you want to check the latest random number against the 10 accepted passwords. If that is correct, you must compare all 10 of them:
int main(void)
{
srand(clock());//for example
j = 0;
while(1)
{
int swipe=rand() % 20;
PORTD=0b00000000;
for(i=0;i<10;i++)
{
j++;
if(swipe == array[i])
{
PORTD=0b10000000;
break;
}
}
//to show ratio of legal to illegal passcodes...
printf("times through: %d Value of PORTD %d\n", j, PORTD);
}
}
if(swipe == a[i]). That invokes Undefined Behaviour as i is 10 and 10 is an out of bounds index. The valid indexes are from 0 to 9.
You are trying to simulate random card-reading actions & get both Pass/Fail at different instances. With swipe values between 1 to 20 and passwords only in the range 10, 19, you'd like to see if some instances fail. Is that correct?
If so, considering your rand() function returns only integer, set a breakpoint and probe for value of swipe. It seems to always has same value. Make rand() function better for wider statistical distribution. There are many sources to generate random integers like Linear Congruential Method etc.
Also that comparison should be looped for every value of array.

calculation of average number get way to high. I don't get why?

I am trying to get the average number of an array but the output is way to high for it to be correct. What am I doing wrong?
int count(int arr[]){
int sum;
//Average
for(int i=0;i<100; i++)
sum = sum + arr[i];
printf("Average:%f \n", sum/100);
}
int main()
{
int array[100]; //RANDOM NUMBERS 0-900
count(array);
return 0;
}
You need to initialize sum to zero before using it. C or C++ does not do this automatically for you in case of variables with automatic storage duration. It takes "time", and in C or C++ you don't pay for what you don't need. Otherwise you get a junk value (whatever its stored at that memory address, and technically it is undefined behaviour to use un-initialized variables except in assignments).
You also need to initialize the array, like
int arr[100]{}; // C++11 or later
or
int arr[100] = {0}; // C++98 or good old C
then fill it up with values. Do not consider the junk values as "random numbers", since again you are encountering undefined behaviour and the program is not altogether safe.
Undefined behaviour(UB):
sum = sum + arr[i];
You have used sum above and it was not initialized. It is UB to read values of uninitialized variables in C and C++.
Actually given your code it is even once again UB because neither array values arr[i] are initialized.
sum contains garbage value. Do initialize variable sumenter code here.
To verify you can print before updating sum.
Try the following:
int count(int arr[]){
int sum = 0; // <==================== initialize to zero
//Average
for(int i=0;i<100; i++)
sum = sum + arr[i];
printf("Average:%f \n", sum/100);
}
int main()
{
int array[100]; //RANDOM NUMBERS 0-900
count(array);
return 0;
}
Without this initialization, the local variable sum can have any arbitrary initial value. And you will end up with arbitrarily large sum. Which will throw off the average.
The reason for this is that local variables are NOT initialized to zero automatically (unlike global variables).

C Finding Maximum and Minimum value? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
In Case of Finding Maximum and minimum Value in Array. We intialize max =0 or max=temp[0];
But in case of Minimum value we doesn't require to initialize min =0 or min=temp[0]... Why?
max = temp[0] acts as reference point. You start comparing each element with this and if any element is greater than this, max value will be updated to that one. similarly min = temp[0] is also valid, but now algorithm will be changed and you need to compare each element if anyone is smaller than this if yes then min will be updated to that.
You always need to initialise variables in C before accessing them; it's undefined behaviour not to. The best thing to do, is, having checked the array length is not zero, is to initialise min / max to the zeroth element. Then loop from the first element.
First, you shouldn't initialize max with 0 in any case (for example, when finding maximum of array which contains all negative values if you initialize max with 0, result will always be 0).
Since for finding maximum (and minimum) you need to compare variable max (or min) with some other value, you need to initialize to temp[0] in any case to avoid comparing array elements with uninitialized variable.
I found the part of your code in another comment:
#include<stdio.h>
int main() {
int arr[3];
int i,max,min; max=min=0;
printf("Enter the value in Array \n");
for(i=1;i<=3;i++) {
scanf("%d",&arr[i]);
}
printf("\n Value of array \n");
for(i=1;i<=3;i++) { printf("%d \n",arr[i]); }
printf("\n Finding Maximum and minimum value \n");
for(i=1;i<=3;i++) {
if(arr[i]>max) max=arr[i];
if(arr[i]<min) min=arr[i];
}
printf("Max = %d \n Min = %d \n ",max,min);
getch();
}
There are few things that doesn't work:
for(i=1;i<=3;i++)
In C, indexing starts from 0, so the valid array elements are arr[0], arr[1] and arr[2], so that for loop should be
for(i = 0; i < 3; i++)
Ok, now imagine that you have in your array elements 10, 5 and 7.
You're setting min value to 0:
max=min=0;
And now you are iterating over this loop:
for(i=0;i<3;i++) {
//...
if(arr[i]<min) min=arr[i];
}
Is 10 < 0? No, it's not.
Is 5 < 0? No, it's not.
Is 7 < 0? No, it's not.
So you see, the min will never change.
To avoid this, just set it to the first element after reading the array:
for(i= 0;i < 3;i++) {
scanf("%d",&arr[i]);
}
min = max = arr[0];
Now, let's repeat our loop:
for(i=0;i<3;i++) {
//...
if(arr[i]<min) min=arr[i];
}
Is 10 < 10? No, it's not.
Is 5 < 10? Yes, it is! Set the min to the 5
Is 7 < 5? No, it's not.
Now the min is 5.
Same issue you have in your existing code with max. Imagine you enter -4, -55 and -20 for elements - max would always stay 0.

Resources