[英]Segmentation Fault with big input
所以我用C ++編寫了這個程序來解決COJ(Caribbean Online Judge)問題1456. http://coj.uci.cu/24h/problem.xhtml?abb=1456 。 它可以很好地處理示例輸入和我編寫的其他一些文件來測試它,但我一直得到'錯誤答案'作為一個預測,所以我決定嘗試使用更大的輸入文件,我得到了Segmentation Fault:11。 該文件長度為1000001,沒有第一個整數,即要測試的輸入數。 我知道錯誤是由與內存相關的東西引起的,但我真的缺少更多的信息。 希望任何人都可以提供幫助,這讓我感到瘋狂。 我主要用Java編程,所以我真的不知道如何解決這個問題。 :(
#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);
}
如果你是用C語言編寫的,你應該改變前幾行,如下所示:
#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
}
這至少會為您的陣列分配適量的內存。
更新說明您可以使用常規訪問這些元素
arr[ii] = 0;
就像你已經將數組聲明為
long arr[N];
(這對你不起作用)。
為了使C ++正確,你必須說服標准委員會在語言中添加可變長度數組。 要使其有效C,您必須包含<stdbool.h>
。
可能你的VLA核對你的堆棧,耗費高達4 * 1000001字節。 (bool只增加了四分之一)除非你使用正確的編譯器選項,否則這可能太多了。
無論如何,你應該使用動態內存。
此外,使用唱歌而不進行初始化是不明智的。
BTW:編程挑戰的最簡單的答案是:將數字讀入數組(使用malloc分配),排序(qsort工作),輸出第一個非重復。
當你寫long arr[N];
您的程序無法正常處理沒有足夠內存來存儲此數組的情況。 充其量,您可能會遇到段錯誤。
但是,使用long *arr = malloc( N * sizeof *arr );
,如果沒有足夠的內存,那么你會發現arr == NULL
,然后你的程序可以采取其他一些動作,例如優雅地退出,或者用較小的數字再次嘗試。
這兩個版本之間的另一個區別是分配內存的位置。
在C(和C ++中),有兩個可以分配變量的內存池: 自動內存和免費存儲 。 在編程術語中,這些術語有時分別稱為“堆棧”和“堆”。 long arr[N]
使用自動區域, malloc
使用免費商店。
您的編譯器和/或操作系統組合決定了每個池中程序可用的內存量。 通常,免費商店可以訪問“大量”內存,這是進程在您的操作系統上可能具有的最大可能性。 但是,自動存儲區域的大小可能有限,並且缺點是如果分配失敗,那么您必須讓您的進程終止或讓您的進程失控。
有些系統使用一個大區域並且自動區域從底部增長,並且免費商店分配從頂部增長,直到它們相遇。 在那些系統上,你可能不會為你的long arr[N]
耗盡內存,盡管同樣的缺點仍然是當它耗盡時無法處理。
因此,您應該更喜歡將免費商店用於任何可能“大”的商店。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.