Absurd value being displayed for the variable 'largest' - c

#include <stdio.h>
int main (void)
{
int phy,geo,i,highest,largest;
int arr[2]={phy,geo};
printf("marks for physics : ");
scanf("%d",&phy);
printf("marks for geo : ");
scanf("%d",&geo);
largest = arr[0];
for (i = 0; i < 2; i++) {
if (arr[i] > largest) {
largest = arr[i];
}
}
// Print out the Result
printf("\nLargest Element : %d", largest);
return(0);
}
I am getting absurd values for the variable 'largest' . It's always the same value no matter what inputs I put in. The purpose of it is to calculate the largest number out of the two inputted numbers.

You're filling your array with uninitialized numbers, that's the source of your "absurd value", then you put your input into variables that are never read, hence why your inputs never change the output.
Try this instead:
printf("marks for physics : ");
scanf("%d", &arr[0]);
printf("marks for geo : ");
scanf("%d", &arr[1]);

Get five spaces in memory filled with whatever was there to begin with:
int phy,geo,i,highest,largest;
Get three spaces in memory, set the last one to null (to show it's the end of an array), and copies the values from two of the earlier five uninitialized spaces into an array:
int arr[2]={phy,geo};
Get two numbers that are input, and write them into two of the five spaces you originally got from memory:
printf("marks for physics : ");
scanf("%d",&phy);
printf("marks for geo : ");
scanf("%d",&geo);
Fill the fifth space in memory with a copy of the value you copied from the first uninitialized space in memory memory into the first element of the array:
largest = arr[0];
For each element in the array (beginning with the one you just copied), if the element is larger than what you've copies into the fifth space in memory, copy it into that space in memory.
for (i = 0; i < 2; i++) {
if (arr[i] > largest) {
largest = arr[i];
}
}
So what you've done is copied uninitialized spots in memory into an array, then taken inputs and written them to those spots in memory, then looked for the largest element in the array. This gives you weird results because you are comparing whatever values happened to be in memory when your program started running.

With the statement
int arr[2]={phy,geo};
you are basically initializing the array with the current values of phy and geo which are as yet uninitialized.
When you later load values through scanf, these won't be reflected in arr.
You need to modify the code as follows:
printf("marks for physics : ");
scanf("%d",&phy);
arr[0] = phy;
printf("marks for geo : ");
scanf("%d",&geo);
arr[1] = geo;

int arr[2]={phy,geo};
This doesn't mean "arr is an array of whatever values phy and geo will hold in the future".
It means "arr is an array of whatever values phy and geo hold now".
And those values are indeterminate because, when you creat arr, neither phy or geo have been initialised yet.

Related

Error: Stack around the variable "m" is corrupted

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.

How to add elements from one array into another array of an undefined size based on a condition?

I have been teaching myself C for just a few weeks, and am attempting to write a code that enables the user to decide the size and elements in an array which is then separated into two arrays - one for odd numbers, and one for even numbers.
I am pretty sure that dynamic allocation has something to do with this, but I am unsure of how to implement it. Here is the code so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
//User decides the size of the array of numbers-------------------------------
int n;
printf("How many numbers? ");
scanf("%d",&n);
//User inputs values into array the size of array[n]--------------------------
int i;
int array[n];
printf("What are the numbers?\n");
for(i=0; i<n; i++)
{
scanf("%d",&array[i]);
}
//loop goes through array, separates even and odds into 2 new arrays----------
//use dynamic allocation??
for(i=0;i<n;i++)
{
int *evenarray = malloc(sizeof(evenarray)); //not sure if this is setup correctly
int *oddarray = malloc(sizeof(oddarray)); //not sure if this is setup correctly
if(array[i] % 2 == 0) //if value in array CAN be divided by 2
{
printf("Test statement.\n");
}
else //if this is not true, append to odd array
{
printf("Second test statement.\n");
}
}
}
/*this program accepts a user chosen number of numbers
then, the program separates the odd and even numbers into
two different arrays*/
There is no magical way to get this information at one shot. You can however, try either of the below:
Loop over the first array to figure out the count of odd (or even) numbers, then, you know the count of elements for which memory has to be allocated, and you can use either a VLA (as the first array itself) or use a pointer and allocator functions to allocate memory.
--> However, in this process, you have to perform the odd/even check twice - once to count the occurrence of odd/even numbers and next time, to actually decide and copy them to the new locations.
Allocate two chunks of memory similar to the first array size, and start filling the odd and even elements into the new memory, respectively. After all the elements are stored, take the counts, realloc() the allocated memories to the exact size.
--> In this case, the pre-allocation is to be done, but the odd/even check needs to be carried out only once.
You could copy into the odd/even arrays and keep seperate counters to track it. i.e:
//loop goes through array, separates even and odds into 2 new arrays----------
//use dynamic allocation??
int evencount =0;
int oddcount =0;
int *evenarray = malloc(sizeof(evenarray)); //not sure if this is setup correctly
int *oddarray = malloc(sizeof(oddarray)); //not sure if this is setup correctly
for(i=0;i<n;i++)
{
if(array[i] % 2 == 0) //if value in array CAN be divided by 2
{
printf("Printing to even array.\n");
evenarray[evencount] = array[i];
evencount++;
}
else //if this is not true, append to odd array
{
printf("Printing to odd array.\n");
oddarray[oddcount] = array[i];
oddcount++;
}
}
printf("evenarray = ");
for(i=0;i<evencount;i++){
printf("%d, ", evenarray[i]);
}
printf("\n");
printf("oddarray = ");
for(i=0;i<oddcount;i++){
printf("%d, ", oddarray[i]);
}
printf("\n");

What does this mean and how do I rectify it *** stack smashing detected ***: ./array1output terminated

This is the code. Why am I facing this error and what source of information should I refer so as to rectify such errors so that I get to know 'If I do this that way, I will get 'x' error'
#include<stdio.h>
void main()
{
int i,avg,sum;
int marks[30]; // Array declaration
for(i=0;i<31;i++)
{
printf("Enter Marks:");
scanf("%d",&marks[i]); // Stores data in Array
}
for(i=0;i<31;i++)
sum=sum+marks[i];
avg=sum/30;
printf("Average marks of student \t %d",avg);
}
Whenever you declare a variable in a function it allocates memory on the stack. The stack is a reserved memory area for doing temporary data manipulation within the function. Now in your code you declared 3 ints and one array of ints with 30 slots. In your for loop you are putting 31 ints into 30 slots; from 0 thru 30 are 31 numbers. The last number is being put beyond the 30th slot and therefore "smashing" into the next spot on the stack, in other words overwriting it. The solution would be to change you for loop to for(i=0;i<30;i++).
You have declared an int type array as [30] and have tried to assign 31 values to it. Please note that the array starts from 0. So the for loop should be as mentioned below.
for(i=0;i<30;i++)
Hence the issue, Please change the for loop and rest are all fine in your code. Thank you. :)
#include<stdio.h>
void main()
{
int i, avg, sum=0;
int marks[30]; // Array declaration
for (i = 0; i<30; i++)
{
printf("Enter Marks:");
scanf("%d", &marks[i]); // Stores data in Array
}
for (i = 0; i<30; i++)
sum = sum + marks[i];
avg = sum / 30;
printf("Average marks of student \t %d", avg);
}

Creating an array in C

I am new to programming and i have been learning C the past few months.
I am working on a program that stores pairs of integers in an array. The program prompts the user to enter the number of pairs to be entered, and then I need to allocate storage for the array and then the user enters the pairs line by line to be stored in the array. The program needs to access these pairs to perform operations on later.
I am having trouble trying to set this up. How can I create this kind of data set, in which each member contains a pair of integers, without knowing the initial size of the array?
There is no built-in support for dynamic array in C. The type that you need is a pointer to your pairs that will be allocated regarding the user choice.
I have written a simple sample code from your description, to help you to understand dynamic allocations.
#include <stdio.h>
#include <stdlib.h>
struct MyPair
{
int first;
int second;
};
int main()
{
int nPairCount=0;
struct MyPair *pPairs = NULL;
// .... prompt from the user
// let's say we have a nPairCount>0
// We allocate a memory space in the heap that will be able to store
// nPairCount pairs contiguously.
pPairs = malloc(nPairCount*sizeof(struct MyPair));
if(pPairs == NULL)
{
// LOG ERROR, THERE IS NOT ENOUGH MEMORY TO ALLOCATE YOUR PAIRS
return -1;
}
for(int i= 0; i<nPairCount; ++i)
{
// you can access the i-th pair in memory thanks to [] operator
// Fill the currentPair
// pPairs[i].first = ... ;
// pPairs[i].second= ... ;
}
// Do your process
// Do not forget to free your pairs from memory
free(pPairs);
return 0;
}
I don't think that there is a bucket function available in c. But you could create an array that has the number of elements entered by the user.
#include<stdio.h>
int main(){
int a,i;
printf("Enter the number of pairs: ");
scanf("%d",&a);
double b[a*2];\\note that a is number of pairs, so 2a will make it elements
printf("Enter the numbers: \n");
for(i=0;i<(2*a-1);i=i+2)
{
scanf("%lf %lf",&b[i],&b[i+1]);
}
printf("The pairs entered by you are:\n ");
for(i=0;i<(2*a-1);i=i+2)
{
printf("%lf and %lf\n ",b[i],b[i+1]);
}
return 0;
}
All I have done is take up 2 elements at a time and assign them consecutive arrays and then print them pairwise.
Sample output:
Enter the number of pairs: 3
Enter the numbers:
12 14
45 456
321 568
The pairs entered by you are:
12.000000 and 14.000000
45.000000 and 456.000000
321.000000 and 568.000000

How to correctly compare and print out matching elements in this array in C?

I have this simple problem to which I am trying to write a solution, in C.
If an array arr contains n elements, then write a program to check
if arr[0] = arr[n-1], arr[1] = arr[n-2] and so on.
And my code looks like this-
#include<stdio.h>
int main()
{
int arr[10],i=0,j;
int k=0;
printf("\n Enter 10 positive integers: \n");
for(k=0;k<=9;k++)
scanf("%d",&arr[k]);
while(i<=9)
{
for(j=9;j>=0;j--)
{
if(arr[i]==arr[j])
{
printf("\n The array element %d is equal to array element %d\n", arr[i],arr[j]);
}
i++;
continue;
}
}
return 0;
}
On entering this input-
Enter 10 positive integers:
10
20
30
40
50
60
40
80
20
90
The output I get is-
The array element 20 is equal to array element 20
The array element 40 is equal to array element 40
The array element 40 is equal to array element 40
The array element 20 is equal to array element 20
Now, there are two problems with this code-
As you can see, the program prints out matching array elements twice. This is because, the way I've structured the program, once the variable i loops through the array from the first to last element, and then j loops through from the last to first element. So each prints out the matching array element once, leading to two sets of values.
My second question is- In my code, I've hard-coded the length of the array in the for loops(0 to 9 for an array of 10 elements). What change can be done so that the length of the array, as entered by the user, can directly be used in the for loops?
I've read that, in C, array dimensions(when declaring) cannot be a variable. So, a declaration like this(which was my first thought) wouldn't work-
int n; // n is no. of elements entered by the user
int arr[n];
I'm a newbie to programming, so my apologies if the question sounds/is too simple, low-quality.
Thank You.
1)You can traverse the array for half times for getting the prints only once. Instead of for(j=9;j>=0;j--) you can use for(j=9;j>=9/2;j--).
2)
int n;
int arr[n].
Recent Compilers support this statement. If you don't like to use this, you can go for dynamic memory allocation for the array.
My second question is- In my code, I've hard-coded the length of the array in the for loops(0 to 9 for an array of 10 elements). What change can be done so that the length of the array, as entered by the user, can directly be used in the for loops?
Use dynamic memory allocation. Use malloc().
So code will be
{
int num_elements;
int* arr;
printf("Enter number of elements\n");
scanf("%d", &num_elements);
arr = (int *) malloc(num_elements * sizeof(int)); // Use this 'arr' for holding input data from user
// Your remaining code comes here
free(arr); // Free the pointer in the end of program
}
the variable length creation works for me:
#include<stdio.h>
int main(){
int a, i;
scanf("%i", &a);
int blah[a];
for (i = 0; i < a; i++){
printf("/n%i", blah[a]);
}
}
The other way would be to create the maximum length array and than simply use first n elements.
As the previous answer states it is up to you to make sure you are checking each element only once therefore stopping at the element n/2. It is probably important that n/2 is rounded to the closest smaller integer, so at first glance odd numbers of arguments may be differently handled. But as it is omitting only the middle element it is identical to itself.
For your first query
for(i=0;i<n/2;i++)
{
if(a[i]==a[n-(i+1)])
{
printf("\n The array element %d is equal to array element %d\n",a[i],a[n-(i+1)]);
}
}
For your second query you can use condition i<(n/2) (which runs the loop (n/2)-1 times) For your case where n = 10 it will run from 0 to 4.
If you want to loop from 0 to 9 you can use
for(i=0;i<n;i++)
For making array of n elements where n is a variable either make an array of elements that is always greater than n or do it by making a dynamic array.
http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html
corrected:
#include<stdio.h>
int main()
{
int i=0, size; // size of array
int k=0; // counter
printf("enter size of array\n");
scanf("%d", &size); // ask user for desired size
int *arr = malloc(size * sizeof(int)); // allocate memory for array
printf("\n Enter 10 positive integers: \n"); // fill your array of size size
for(k=0;k<size;k++)
scanf("%d",&arr[k]);
k = 0; // reset this counter
for(i=0; i<size/2; i++) // check only for half of it
{
if(arr[i] == arr[size-i-1]) // try it with paper and pincil
{
printf("match arr[%d]=arr[%d]=%d\n", i,size-i-1, arr[i]);
k++;
}
}
if(k==0) printf("No matching");
return 0;
}

Resources