Munna Lal Joshi
Munna Lal Joshi

Reputation: 11

Why for loop terminates after running only 4 times?

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

Upvotes: 0

Views: 120

Answers (5)

0___________
0___________

Reputation: 67820

#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 */
}

Upvotes: -1

R Sahu
R Sahu

Reputation: 206697

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

Upvotes: 1

WhozCraig
WhozCraig

Reputation: 66244

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.

Upvotes: 1

kiran Biradar
kiran Biradar

Reputation: 12742

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

Upvotes: 1

Alex Johnson
Alex Johnson

Reputation: 958

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.

Upvotes: 1

Related Questions