Darwin57721
Darwin57721

Reputation: 197

Segmentation Fault with big input

So I wrote this program in C++ to solve COJ(Caribbean Online Judge) problem 1456. http://coj.uci.cu/24h/problem.xhtml?abb=1456. It works just fine with the sample input and with some other files I wrote to test it but I kept getting 'Wrong Answer' as a veredict, so I decided to try with a larger input file and I got Segmentation Fault:11. The file was 1000001 numbers long without the first integer which is the number of inputs that will be tested. I know that error is caused by something related to memory but I am really lacking more information. Hope anyone can help, it is driving me nuts. I program mainly in Java so I really have no idea how to solve this. :(

#include <stdio.h>

int main(){

long singleton;
long N;

scanf("%ld",&N);
long arr [N];
bool sing [N];

for(int i = 0; i<N; i++){
    scanf("%ld",&arr[i]);
}

for(int j = 0; j<N; j++){   

    if(sing[j]==false){     

        for(int i = j+1; i<N; i++){

            if(arr[j]==arr[i]){
                sing[j]=true;
                sing[i]=true;
                break;
            }


        }
    }

    if(sing[j]==false){
        singleton = arr[j];
        break;
    }
}

printf("%ld\n", singleton);
}

Upvotes: 0

Views: 2443

Answers (3)

M.M
M.M

Reputation: 141544

When you write long arr[N]; there is no way that your program can gracefully handle the situation where there is not enough memory to store this array. At best, you might get a segfault.

However, with long *arr = malloc( N * sizeof *arr );, if there is not enough memory then you will find arr == NULL, and then your program can take some other action instead, for example exiting gracefully, or trying again with a smaller number.

Another difference between these two versions is where the memory is allocated from.

In C (and in C++) there are two memory pools where variables can be allocated: automatic memory, and the free store. In programming jargon these are sometimes called "the stack" and "the heap" respectively. long arr[N] uses the automatic area, and malloc uses the free store.

Your compiler and/or operating system combination decide how much memory is available to your program in each pool. Typically, the free store will have access to a "large" amount of memory, the maximum possible that a process can have on your operating system. However, the automatic storage area may be limited in size , as well as having the drawback that if allocation fails then you have to have your process killed or have your process go haywire.

Some systems use one large area and have the automatic area grow from the bottom, and free store allocations grow from the top, until they meet. On those systems you probably wouldn't run out of memory for your long arr[N], although the same drawback remains about not being able to handle when it runs out.

So you should prefer using the free store for anything that might be "large".

Upvotes: 0

Deduplicator
Deduplicator

Reputation: 45654

To make it proper C++, you have to convince the standard committee to add Variable length arrays to the language. To make it valid C, you have to include <stdbool.h>.

Probably your VLA nukes your stack, consuming a whopping 4*1000001 byte. (The bool only adds a quarter to that) Unless you use the proper compiler options, that is probably too much.

Anyway, you should use dynamic memory for that.

Also, using sing without initialisation is ill-advised.

BTW: The easiest C answer for your programming challenge is: Read the numbers into an array (allocated with malloc), sort (qsort works), output the first non-duplicate.

Upvotes: 0

Floris
Floris

Reputation: 46365

If you are writing in C, you should change the first few lines like this:

#include <stdio.h>
#include <stdlib.h>

int main(void){

  long singleton;
  long N;

  printf("enter the number of values:\n");
  scanf("%ld",&N);

  long *arr;
  arr = malloc(N * sizeof *arr);
  if(arr == NULL) {
    // malloc failed: handle error gracefully
    // and exit
  }

This will at least allocate the right amount of memory for your array.

update note that you can access these elements with the usual

arr[ii] = 0;

Just as if you had declared the array as

long arr[N];

(which doesn't work for you).

Upvotes: 2

Related Questions