2010-06-16 27 views
5

Tôi có một thuật toán để tạo rây Eratosthenes và kéo số nguyên tố từ nó. Nó cho phép bạn nhập giá trị tối đa cho rây và thuật toán cung cấp cho bạn số nguyên tố bên dưới giá trị đó và lưu trữ các giá trị này trong một mảng kiểu c."EXC_BAD_ACCESS: Không thể khôi phục khung đã chọn trước đó" Lỗi, kích thước mảng?

Vấn đề: Tất cả mọi thứ hoạt động tốt với các giá trị lên đến 500.000, tuy nhiên khi tôi nhập một giá trị lớn -while running- nó mang lại cho tôi được thông báo lỗi sau đây trong xcode:

Program received signal: “EXC_BAD_ACCESS”. 
warning: Unable to restore previously selected frame. 
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.) 

ý tưởng đầu tiên của tôi là tôi không sử dụng các biến đủ lớn, nhưng khi tôi đang sử dụng 'unsigned long long int', điều này không phải là vấn đề. Ngoài ra, trình gỡ rối chỉ cho tôi một điểm trong mã của tôi, nơi một điểm trong mảng được gán một giá trị. Vì vậy, tôi tự hỏi là có một giới hạn tối đa cho một mảng? Nếu có: tôi có nên sử dụng NSArray thay thế không? Nếu không, thì điều gì gây ra lỗi này dựa trên thông tin này?

EDIT: Đây là mã trông như thế nào (nó không hoàn chỉnh, vì nó không thành công ở dòng cuối cùng được đăng). Tôi đang sử dụng bộ sưu tập rác.

/*--------------------------SET UP--------------------------*/ 
    unsigned long long int upperLimit = 550000;    // 
    unsigned long long int sieve[upperLimit]; 
    unsigned long long int primes[upperLimit]; 
    unsigned long long int indexCEX; 
    unsigned long long int primesCounter = 0; 

// Fill sieve with 2 to upperLimit 
for(unsigned long long int indexA = 0; indexA < upperLimit-1; ++indexA) { 
     sieve[indexA] = indexA+2; 
} 


unsigned long long int prime = 2; 

/*-------------------------CHECK & FIND----------------------------*/ 
while(!((prime*prime) > upperLimit)) { 

    //check off all multiples of prime 
    for(unsigned long long int indexB = prime-2; indexB < upperLimit-1; ++indexB) { 

     // Multiple of prime = 0 
     if(sieve[indexB] != 0) { 
      if(sieve[indexB] % prime == 0) { 
       sieve[indexB] = 0; 
      } 
     } 
    } 

    /*---------------- Search for next prime ---------------*/ 
    // index of current prime + 1 
    unsigned long long int indexC = prime - 1; 

    while(sieve[indexC] == 0) { 
     ++indexC; 
    } 
    prime = sieve[indexC]; 

    // Store prime in primes[] 
    primes[primesCounter] = prime; // This is where the code fails if upperLimit > 500000 
    ++primesCounter; 

    indexCEX = indexC + 1; 

} 

Như bạn có thể thấy hoặc không thấy, là tôi rất - một người mới bắt đầu. Bất kỳ đề xuất nào khác đều được hoan nghênh tất nhiên :)

+1

Sẽ dễ dàng hơn để gỡ lỗi này nếu bạn đăng mã. –

Trả lời

7

Bạn không làm tràn biến; bạn đang tràn ngăn xếp. Khi bạn tạo một mảng như int myArray[500], bạn đang khai báo 500 int s trên ngăn xếp. Kích thước ngăn xếp thông thường là 8 MB. Hai mảng của bạn một mình là khoảng 8,4 MB (8 byte * 550000/(1024^2) = 4,2 MB). Bạn nên sử dụng bộ nhớ heap (từ malloc()) ở đây để thay thế. Vì vậy, nó sẽ như thế này:

int upperLimit = 550000; 
unsigned long long *sieve = malloc(sizeof(long long) * upperLimit); 
unsigned long long *primes = malloc(sizeof(long long) * upperLimit); 
unsigned long long indexCEX; 
unsigned long long primesCounter = 0; 

Đừng quên rằng bạn sẽ cần phải free() bộ nhớ khi bạn đang thực hiện xong hoặc bạn sẽ bị rò rỉ.

+0

Cảm ơn rất nhiều! Điều này làm việc :) – Job

0

Như tôi biết, "EXC_BAD_ACCESS" được nhận, khi bạn cố gắng làm việc với bộ nhớ đã giải phóng. Để gỡ lỗi này, bạn có thể sử dụng lớp NSZombie. Điều này có thể giúp: http://www.cocoadev.com/index.pl?DebuggingAutorelease

+0

Điều này không liên quan đến mã của tôi khi tôi đang sử dụng bộ sưu tập rác. Thanks anyway :) – Job

2

Bạn đang sử dụng mảng được phân bổ trên ngăn xếp. Bạn có thể phân bổ nhiều bộ nhớ hơn nếu bạn sử dụng phân bổ bộ nhớ động:

/* program setup */ 
unsigned long long *sieve = malloc(sizeof(*sieve) * upperLimit); 
unsigned long long *primes = /* -- "" -- */ 
/* etc, free() at program end */ 

Giới hạn ngăn xếp trên hệ điều hành OS X có thể là 8 MiB. Nếu sizeof(unsigned long long) == 8 trên hệ thống của bạn, bạn sẽ phù hợp với hai mảng 500.000 phần tử trong ngăn xếp của bạn, nhưng không phải là hai mảng 550000 phần tử.

0

Tôi cũng gặp sự cố này. Hóa ra tôi đã có vòng lặp. Tôi vô tình gọi một phương pháp từ bên trong.

+0

Bạn có thể vui lòng cung cấp thêm một số chi tiết hoặc một ví dụ không? – Foo

+0

Oy ... đã một tuổi rồi. Thật không may tôi thậm chí không nhớ. Nhưng nếu bạn làm - (void) phương pháp {[tự phương pháp]; } –

Các vấn đề liên quan