I wanted to expand an array dynamically as the user enters the values using below code.
#include<stdio.h>
#include<stdlib.h>
int main(){
int *number=(int *)malloc(sizeof(int)),i=0,*new_ptr;
printf("Enter a number to store it or -1 to finish the storage\n");
scanf("%d",number);
while(*(number+i)!=-1){
printf("Enter a number to store it or -1 to finish the storage:\n");
number=(int *)realloc(number,sizeof(number)+sizeof(int));
i++;
scanf("%d",number+i);
};
for(int j=0;j<i;j++){
printf("%d ",number[j]);
};
return 0;
}
it gives this output
Enter a number to store it or -1 to finish the storage
1
Enter a number to store it or -1 to finish the storage:
2
Enter a number to store it or -1 to finish the storage:
3
Enter a number to store it or -1 to finish the storage:
4
Enter a number to store it or -1 to finish the storage:
5
Enter a number to store it or -1 to finish the storage:
6
Enter a number to store it or -1 to finish the storage:
7
Enter a number to store it or -1 to finish the storage:
8
Enter a number to store it or -1 to finish the storage:
9
Enter a number to store it or -1 to finish the storage:
0
Enter a number to store it or -1 to finish the storage:
-1
1 2 3 4 5 6 7 8 540155953 540287027
the junk file values happens only when the number of user input is greater than 8. Why it happens and how to fix it?
There were a few small issues with the original code. Junk values got printed because the original code invoked undefined behavior. Specifically, realloc() was not allocating enough space in the old logic. realloc() needs to know new total space.
Original code was always realloc()ing sizeof(number)+sizeof(int)... which translates to sizeof(int *) + sizeof(int).
That combo results in a constant which does not grow. This may at least partly explain why you could get OK performance until the array actually needed more space than sizeof(int *) + sizeof(int). The new code fixes that by updating the allocation size logic.
Other adds/updates:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *number=malloc(sizeof(int)), *temp, i=0,j, sres,scap;
if(!number)
{
/* malloc() problem. Alert user and exit. */
printf("Coule not allocate memory!\n");
return 0;
}
/* The do / while() loop design eliminates redundancy of the
** scanf() prompt and fetch. We prompt user and scan()
** in a single code block. */
do {
printf("Enter a number to store it or -1 to finish the storage:\n");
/* Use a separate, new variable to capture the scanf() input */
sres = scanf("%d", &scap); /* Added: always check the return of scanf()*/
if(sres!=1)
{
/* scanf() problem. Alert user and exit. */
printf("scanf() error!\n");
return 0;
}
/* New logic/sequence. If the captured value is not -1, store and continue*/
if(scap != -1)
{
number[i++] = scap; /* Store input to array */
/* Updated allocation size logic: (i+1) means current count + next input: */
temp = realloc(number, (i+1)*sizeof(number));
if(temp)
{
/* Preserve number pointer. Only assign new
** memory if allocation was successful*/
number = temp;
}
else
{
/* realloc() problem. Alert user and exit. */
printf("Coule not allocate memory for next input!\n");
return 0;
}
}
}while(scap != -1); /* Condition modified to adapt to new logic*/
for(j=0;j<i;j++)
{
printf("%d ",number[j]);
}
return 0;
}
Output:
Enter a number to store it or -1 to finish the storage:
1
Enter a number to store it or -1 to finish the storage:
2
Enter a number to store it or -1 to finish the storage:
3
Enter a number to store it or -1 to finish the storage:
4
Enter a number to store it or -1 to finish the storage:
5
Enter a number to store it or -1 to finish the storage:
6
Enter a number to store it or -1 to finish the storage:
7
Enter a number to store it or -1 to finish the storage:
6
Enter a number to store it or -1 to finish the storage:
5
Enter a number to store it or -1 to finish the storage:
4
Enter a number to store it or -1 to finish the storage:
3
Enter a number to store it or -1 to finish the storage:
2
Enter a number to store it or -1 to finish the storage:
1
Enter a number to store it or -1 to finish the storage:
-1
1 2 3 4 5 6 7 6 5 4 3 2 1