I want to find the minimum number and summary from a dynamic integer table. I do not know why results not shown. Have I done something wrong on the malloc ? May I use realloc too ?
#include <stdlib.h>
#include <stdio.h>
int main()
{
int n,i,min,sum,xronos;
int* array;
printf("Give me how many numbers does the table will have: \n");
scanf("%d",&n);
array=(int*)malloc(n*sizeof(int));
for(i=1;i<=n;i++)
{
printf("Give the number %d",i);
printf("\n");
scanf("%d",&array[i]);
}
for(i=1;i<=n;i++)
{
sum=sum+array[i];
if (i=1)
{
min=array[i];
}
else
{
if (array[i]<min)
{
min=array[i];
}
}
}
printf("%d",sum);
printf("\n The answer is :",(n-2)*min+(sum-min));
getch();
return 0;
}
Yes, that is almost exactly how you are supposed to use malloc, except for three small things and one big thing:
Do not cast malloc result in C,
Use indexes from zero to n-1, inclusive (your code goes from one to n, inclusive)
Add a call free(array) to avoid a memory leak.
The big thing is that you do not need malloc in order to solve this problem: you can calculate the sum and the min as you go, without saving the individual items to an array.
You can replace the chain of ifs in the loop with this check:
if (i == 0 || array[i] < min) {
min=array[i];
}
This covers both the assignment of the first element, and comparison of elements other than the first one.
Finally, you can rewrite this
sum=sum+array[i];
as
sum += array[i];
using a composite assignment operator. Don't forget to initialize the sum to zero!
#include <stdlib.h>
#include <stdio.h>
#include <errno.h> /* Defines: ENOMEM */
int main()
{
Added rCode to assist in error handling.
int rCode=0;
Removed xronos as it is not used.
int n,i,min;
Initialized sum to 0;
int sum=0;
Initialize array pointer to NULL so cleanup is easier.
int *array = NULL;
printf("Give me how many numbers does the table will have: \n");
scanf("%d",&n);
There is nothing inherently wrong with casting the output of malloc to (int *). In some situations, it is a good coding practice. (good job).
array=(int*)malloc(n*sizeof(int));
You should always test that you actually got memory from malloc.
if(NULL == array)
{
rCode=ENOMEM;
fprintf(stderr, "malloc() failed.");
goto CLEANUP;
}
The array element index is in the range of 0 through (n-1). Start indexing at zero, and be sure to stop at (n-1).
for(i=0;i<n;i++)
{
printf("Give the number %d",i);
printf("\n");
scanf("%d",&array[i]);
}
Again, the array element index is in the range of 0 through (n-1). Start indexing at zero, and be sure to stop at (n-1).
for(i=0;i<n;i++)
{
sum=sum+array[i];
if(1 == i)
min=array[i];
else
{
if(array[i] < min)
min=array[i];
}
}
printf("%d",sum);
printf("\n The answer is :",(n-2)*min+(sum-min));
getch();
CLEANUP:
From my early years, my father would tell me: 'When you bring your toys to the sandbox, always remember to put them away when you are finished.'
if(array)
free(array);
return(rCode);
}
Line 22, need
if (i=1)
set to
if (i==1)
Right now you're setting i equal to 1
Related
SS4SS of 3rd Problem
I want to create the program to take the input from user until he presses 1.
I'm using dynamic memory allocation using function and after running this code, this program takes only 4 input and it does not show any output
output
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void input(int **arr)
{
int n=1,i=0;
*arr=(int *)malloc(sizeof(int));
int ch;
do
{
printf("\nEnter '1' To Enter A Value in array or else enter '0'");
scanf("%d",&ch);
if (ch==1)
{
if (!*arr)
{
printf("\nInsufficient Memory!");
return;
}
printf("\nEnter the value\t:\t");
scanf("%d", arr[i]);
*arr=realloc(*arr,sizeof(int)*(++n));
*arr[++i]=INT_MIN;
}
else if (ch!=1&&ch!=0)
{
printf("\nInvalid input!");
continue;
}
} while(ch!=0);
free(arr);
}
void display(int **arr)
{
for (int i = 0; i < 3; i++)
printf("\n%d", **(arr+i));
free(arr);
}
int main()
{
int *arr;
input(&arr);
display(&arr);
free(arr);
return 0;
}
First question
With !*arr[i] you are checking the logical value contained in *arr[i], which can have a random value before you assign a value to it. In your case, the value contained in *arr[i] is 0, triggering the condition !*arr[i].
The correct way of checking if realoc() was succesful, is checkin it's returned value. If it's null, the request failed. In your case, it would be replacing
if(!*arr[i])
by
if(!*arr)
Second question
In this line *arr[++i]=INT_MIN; the index [] operator has precedence over pointer * operator. You have to write parenthesis:
(*arr)[++i]=INT_MIN;
And also here
scanf("%d", arr[i]);
you are saying that arr is an array, when it is a pointer to an array. You should replace it with:
scanf("%d", *arr + i);
Third question
You are also doing free() before you access the values in the array, which triggers the error. You should remove the free() calls at the end of input() and display() and leave only the one of the end of main().
You have still to replace the printf() in display with
printf("\n%d", (*arr)[i]));
I want that array (marks) size increases by 1 with each input of user:
#include <stdio.h>
main() {
int size=1;
int marks[size];
int i;
printf("Enter marks\n");
for(i=0;i<size;i++) {
scanf("%d",&marks[i]);
size++;
}
}
You can't increase the size of your array dynamically. But if you know how many scores will be entered, then you can set size to that value and then accept values until that size is reached.
#include <stdio.h>
int main()
{
int size = 10;
int marks[size];
int i;
printf("Enter marks\n");
for(i = 0; i < size; i++)
{
scanf("%d",&marks[i]);
}
}
Resizing dynamically will increase the complexity of your program significantly, but if that's exactly what you're trying to do, check out R Sahu's answer here or this answer: increasing array size dynamically in c.
Because you have statically declared marks array to size 1. Since you are incrementing size in loop will lead to undefined behavior. Better approach would be allocate marks dynamically.
Consider below example for reference.
#include <stdio.h>
#include<stdlib.h>
void main() {
int size=0;
int *marks = NULL;
int i;
printf("Enter number of marks\n");
scanf ("%d",&size);
marks = (int *) malloc(size*sizeof(int));
printf("Enter marks\n");
for(i=0;i<size;i++)
{
scanf("%d",&marks[i]);
}
}
Your code assumes an increase in size will increase the size of the native array. That isn't how arrays work in C.
Native arrays in C are fixed-length after their definition. If you want to dynamically grow a sequence of things, then you need to manage a dynamic sequence, doing it inner-loop as valid data is received.
Code
The following prompts (or lack thereof) the user in the same fashion your code apparently desired. However, a loop termination condition has been added (a mark entry of -1 will terminate the loop, as will any invalid non-convertible input).
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *marks = NULL, mark = 0;
int size = 0;
printf("Enter marks\n");
while (scanf("%d", &mark) == 1 && mark != -1)
{
// expand marks
void *tmp = realloc(marks, (size+1) * sizeof *marks);
if (tmp == NULL)
{
perror("Failed to expand marks array");
exit(EXIT_FAILURE);
}
marks = tmp;
marks[size++] = mark;
}
// TODO: use marks[0] through marks[size-1] here
for (int i=0; i<size; ++i)
printf("%d ", marks[i]);
fputc('\n', stdout);
// then free marks
free(marks);
return EXIT_SUCCESS;
}
Sample Input
1 2 3 4
5 6
7 8 9
10 -1
Output
1 2 3 4 5 6 7 8 9 10
Notes: There are more efficient geometric growth algorithms that considerably reduce the number of realloc calls, For example, doubling the prior sequence size with each realloc and tracking both size and capacity would reduce your number of allocations from n to log(n). However, for the basic understanding of inline sequence growth, this example should suffice.
I want that array (marks) size increases by 1 with each input of user.
That's not how arrays work in C.
To get that functionality, you'll have to use dynamically allocated memory using malloc and realloc.
Also, your code has a logic flaw. If you look at the variables that control the loop, you have:
int size=1;
int i;
for(i=0;i<size;i++) { // i will never catch up to size before size overflows
size++;
}
For your needs, you can use a variable length array (VLA) or use malloc only once.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size;
int i;
printf("Enter size\n");
if ( scanf("%d", &size) != 1 )
{
// Problem. Deal with error.
}
// Use a VLA
int marks[size];
// or
// Allocate memory.
// int* marks = malloc(sizeof(*marks)*size);
printf("Enter marks\n");
for ( i = 0; i < size; i++)
{
if ( scanf("%d", &marks[i]) != 1)
{
// Problem. Deal with error.
}
}
// Deallocate the memory. Needed when using malloc
// free(marks);
}
#include <stdio.h>
#include <stdlib.h>
main() {
int size=1;
int *marks = NULL;
int i;
printf("Enter marks\n");
for(i=0;i<size;i++)
{
int *tmpptr = realloc(marks, size * sizeof(*mark));
if(!tmpptr)
{
printf("Memeory allocation error\n");
free(marks);
break;
}
marks = tmpptr;
if(scanf("%d",marks + i) != 1) break;
size++;
}
/* some code */
}
it asks two questions at once,why?
here is my code:
#include <stdio.h>
int main()
{
int i,j;
int n;
int adjmatrix[n][n];
char ans;
printf("How many vertices?");
scanf("%d",&n);
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
printf("Are vertex %d and %d adjacent?",i,j);
scanf("%c",&ans);
if (ans=='Y' || ans=='y')
{
adjmatrix[i][j]=1;
}
else adjmatrix[i][j]=0;
}
}
return 0;
}
Thanks in advanceļ¼
You're right. The output is weird.
Your problem is scanf. Use scanf("%2c", ans);. Helped me.
But even then, i had the problem that the loops are not iterated
correctly.
Explanation:
The reason was the matrix. The matrix is not allocating any memory because its size if variable.
Therefore by setting an entry of the matrix to 1, this influences the variable j.
Solution:
You need to solve the problem to dynamically allocate memory.
Have a look at:
https://www.eskimo.com/~scs/cclass/int/sx9b.html
https://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/
I'm trying to create a program that asks the user for a size of an array, then asks the user to populate it.
Whenever I launch the program, the "Element %d" printf displays the %d as a large number instead of 1.
If I continue the program after entering the value into the array, the debugger crashes. What's happening here? Did I accidentally place the address in the array position? Thanks
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elements = 0;
printf("How many Elements will you enter?");
scanf("%d", &elements);
int* elementArray = malloc(sizeof(int) * elements);
int i = 0;
while (elementArray[i] != '\0')
{
printf("Element %d: ", elementArray[i]);
scanf("%d", &elementArray[i]);
i++;
}
free(elementArray);
return 0;
}
EDIT: Reading the comments, I meant printf("Element %d: ", elementArray[i]); was supposed to print one during the first loop. Though I should edit the code to be elementArray[i] + 1 so it doesn't print "Element 0" instead of Element 1. Apologies for the barebones code, it's half finished, I wanted to solve this problem before finishing it off. Will work on the solutions given now. Thanks for the help
EDIT2: Thanks to all of you, especially Sharuya! Here's my finished code.
void printArray(int* elemArray, int elements)
{
printf("The Array contains: ");
for (int k = 0; k < elements; k++)
{
printf("%d,\t", elemArray[k]);
}
}
int main(void)
{
int elements = 0;
printf("How many Elements will you enter?");
scanf("%d", &elements);
int* elementArray = (int *)malloc(sizeof(int) * elements);
int input = 0;
for (int j = 0; j < elements; j++)
{
printf("Element %d: ", j + 1);
scanf("%d\n", &input);
*(elementArray + j) = input;
}
printArray(elementArray, elements);
free(elementArray);
return 0;
}
Only issue now is, between the "Element 1: " and "Element 2: " printf, I get a blank line, that allows me to enter a number, upon submitting, it continues as normal. If I submit an array with 5 elements, It asks me for 6 elements, and only 5 appear... What's happening here?
while (elementArray[i] != '\0')
This check is the problem
malloc gives no guarantee that the memory initialized will be zero filled. Hence your loop may cross over the allocated memory and try to read memory that your program is not supposed to read (hence resulting in a crash)
If it's zero filled your code will never enter the loop
What you need is
while (i < elements)
Also printf should come after scanf for any meaningful result. If you want to just get the index that you are about to enter use printf("Element: %d", i) instead of elementArray[i]
A couple of questions, for you to ask:
What if the user enters a negative value?
What if the user enters 0 ?
What if the user enters a very large value?
Did the array allocation succeed?
What is in my array after it is allocated?
If my array size is 0, will elemenArray[0] be valid?
Should I use a for loop, like everyonbe else does for walking through my array?
Just asking yourself these questions will fix this program in no time, and will get you through half of the next one you'll write.
You have more problems than the fact that you print something else than the index.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elements = 0;
printf("How many Elements will you enter? ");
if((1!=scanf("%d", &elements))||(elements<1) ) // check return value, always a good idea
{ printf("Reading number failed.\n");
return 1;
}
int* elementArray = malloc(sizeof(int) * elements);
int i = 0;
while ( (i<elements) // use the number you asked for to avoid writing beyond array
&& ((0==i) || (0 != elementArray[i-1]))) // stop when previously entered value is 0
{
printf("Element %d: ", i+1); // print the index
// instead of the non-initialised value
if(1!= scanf("%d", &elementArray[i]))
{
printf("Reading value failed!\n");
free(elementArray); // cleanup
return 1;
}
i++;
}
if (i<elements)
{
printf("Stopped early because 0 was entered.\n");
}
free(elementArray);
return 0;
}
First you need to know that malloc() function dynamically allocates memory according to the size calculated (with the help of sizeof() ) and returns the address of this memory location.
However this address is not associated with any data type i.e. only a void* pointer can store this address of an incomplete data type.
Thus instead of mentioning
int* elementArray = malloc(sizeof(int) * elements);
mention and use typecasting to it
int* elementArray = (int *)malloc(sizeof(int) * elements);
As per your code, elementArray is a pointer which will store the address of an integer
int *elementArray;
printf("Element %d: ", elementArray[i]);
Thus the above line will actually print the address pointed to by the pointer and not the index since incrementing a pointer is same as
elementArray stores the base address.
i.e elementArray++ is equal to elementArray+1 == elementArray[1] will point
to the next memory location after 4 bytes.(since integer is stored in 4 bytes)
I have modified your code correcting your mistakes
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int elements = 0;
printf("How many Elements will you enter?");
scanf("%d", &elements);
//the below statement actually allocates contiguous block of memory equal
//to no of elements and the pointer points only to first element.
//Incrementing it will point to next element
int* elementArray =(int *) malloc(sizeof(int) * elements);
//typecasting of void* pointer to int*
int i = 0,elm;
for(i=0;i<elements;i++)
//Since u know iterations will be equal to no of elements it is better to use for loop
{
printf("Element %d: ", i);
scanf("%d", &elm);
*(elementArray+i)=elm;
//Storing the data in elm and making the pointer point to next free
//dynamically allocated block of memory and using * operator the value at
//this location is accessed and storing elm value in it
}
for(i=0;i<elements;i++)
printf("%d",*(elementArray+i));
free(elementArray);
return 0;
}
This code works and I hope it make things clear !!!
I am trying to calculate factorial of very large numbers in c like 100!..by dynamically allocating memory after calculating the number of digits in factorial:
My code is:
int main()
{
int n,q,i,j,z,t,d;
float p=0.0;
printf("Enter the number whose factorial is to be calculated:\n");
scanf("%d",&n);
//calculating number of digits
for(j=2;j<=n;j++)
p=p+log10(j);
d=(int)p+1;
printf("No of digits in the factorial are:%d\n",d);
int *a;
a=(int *)malloc(d*sizeof(int));//allocation of memory
a[0]=1;
for(i=1;i<n;i++)//initialize array
a[i]=0;
p=0.0;
for(j=2;j<=n;j++)
{
q=0;
p=p+log10(j);
z=(int)p+1;
for(i=0;i<z;i++)
{
t=(a[i]*j)+q;
q=t/10;
a[i]=t%10;
}
}
printf("\n");
for(i=d-1;i>=0;i--)
{
printf("%d",a[i]);
}
return 0;
}
Its providing correct answers upto 40! but not after that!What is wrong with my solution?
The problem is probably because of this loop:
for(i=1;i<n;i++)//initialize array
In the loop you clear the n - 1 entries of the allocated memory, but you allocate memory for d entries. If n - 1 is larger than d then you write outside the allocated memory, which causes undefined behavior. If n - 1 is smaller than d then you leave some memory uninitialized which also is undefined behavior when you access it.
You should clear all of the memory, either by using your loop, by using memset or by using calloc when allocating.
may be you can use memset in case not quite interested in calloc, also I guess null check is mandatory
so instead of this looping
a=(int *)malloc(d*sizeof(int));//allocation of memory
a[0]=1;
for(i=1;i<n;i++)//initialize array
a[i]=0;
a simple call
a=(int *)malloc(d*sizeof(int));//allocation of memory
if(a == NULL)
{
printf("OOM Error");
exit(1);
}
memset(a, 0 , d*sizeof(int));
int main()
{
int i,j,n,m=0;
scanf("%d",&n);
int arr[2000];
int temp=0;
int inter=1;
arr[0]=1;
for(i=1;i<n;i++)
{
for(j=0;j<=m;j++)
{
inter=arr[j]*i+temp;
arr[j]=inter%10;
temp=inter/10;
if( temp>0 && j==m )
m++;
}
}
for(i=m;i>=0;i++)
{
printf("%d",arr[i]);
}
return 0;
}