Click here to Skip to main content
15,907,326 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
The follow program is wrong.It will be loop indefinitely.
C++
#include <stdio.h>

int main() {
    int N;
    int arr[20] = {};
    scanf("%d", &N);
    for (int i = 1; i <= N; i++)
    {
        int sum = 0;
        int n = 0;
        for (int j = 1; j < i; j++)
        {
            if (i % j == 0)
            {
                sum += j;
                *(arr+n) = j;
                n++;
            }
                
        }
        if (i == sum)
        {
            printf("%d its factors are ", i);
            for (int i = 0; i < n; i++)
            {
                printf("%d ", arr[i]);
            }
            printf("\n");
        }
        else
            continue;
    }
    return 0;
}


What I have tried:

The program is looping indefinitely.If I modify the arr[20] to arr[1000],the program is correct.I do not know the reason.
Posted
Updated 18-Apr-23 9:01am
v2
Comments
Patrice T 18-Apr-23 3:08am    
What input ?
merano99 18-Apr-23 14:10pm    
Why do you tag the code as C++ when it is 100% C code?

Remember that you have nested loops, and as it iterates through each pass of the outer loop, i grows. Because the value of i is the count controlling how many times the inner loop iterates, the total iterations will be dependent on N and will grow quickly. Since you have no checks on n within your loop, it can easily exceed the 20 elements you allocated to the array, and start overwriting other memory. If that memory includes i, j, n, or N then your loop guards get overwritten, and the problem escalates.

You should allocate an array where the size is dependent on the value of N rather than a fixed value!

BTW: Your else ... continue code is completely redundant!
 
Share this answer
 
Quote:
I do not know the reason.

Read your code carefully!
C++
#include <stdio.h>

int main() {
    int N;
    int arr[20] = {};
    scanf("%d", &N);
    for (int i = 1; i <= N; i++)  // i is the main loop
    {
        int sum = 0;
        int n = 0;
        for (int j = 1; j < i; j++)
        {
            if (i % j == 0)
            {
                sum += j;
                *(arr+n) = j;
                n++;
            }
                
        }
        if (i == sum)
        {
            printf("%d its factors are ", i);
            for (int i = 0; i < n; i++) // and i is this inner loop
            {
                printf("%d ", arr[i]);
            }
            printf("\n");
        }
        else
            continue;
    }
    return 0;
}

The i in inner loop kills the main loop every times you get a result.
 
Share this answer
 
Comments
CPallini 18-Apr-23 2:45am    
Nope, the i in the inner loop is a fresh variable shadowing the outer scope one.
Patrice T 18-Apr-23 3:03am    
Oups
As Griff correctly pointed out, your problem is in the following lines
C++
*(arr+n) = j;
  n++;

You don't know in advance how much n will grow (albeit it cannot be greater than N*N), so arr overrun is easily achieved.

If you are actually using C++ (as the tag implies) then choose a vector, instead of C-like array. On the other hand, if you are using C then you should use dynamic memory allocation, calling realloc (see, for instance realloc in c example | How realloc works | return value of realloc| realloc code[^]) whenever arr needs to grow.
 
Share this answer
 
The strange array access can also be written in a simpler and more readable way:
C
// *(arr + n) = j;
arr[n] = j;

As OriginalGriff already stated else continue; can be removed completely.

To find the error it makes sense to monitor the array size.
First I would calculate in a variable how many elements the array arr can hold:
C
int arr[20] = {};
size_t arr_size = sizeof(arr) / sizeof(arr[0]);

Before each access to the field, we can now check whether the index is still in the field or not:
C
if (n < arr_size) {
  // *(arr + n) = j;
  arr[n] = j;
}
else
  printf("error: n is too big %d\n", n);
}

As you can easily see the field arr e.g. for N=360 with only 20 elements is not enough to store all numbers and the field overflows.

To look at the problem you can of course output all N that are too large:
C
if(n >= arr_size)
  printf("for i=%d, n was %d\n", i, n);
if (i == sum) {

for i=360, n was 23

For N to 1000, the arr field would have to contain at least 32 elements.
 
Share this answer
 
v2
Comments
1beginner1 20-Apr-23 11:02am    
Thanks for you answer.It is so useful.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900