2013-10-01 23 views
11

Điều này tạo ra một Segmentation Fault: 11 và tôi không có đầu mối tại sao.Lỗi phân đoạn Python?

Trước khi tôi nhận được vào nó, đây là các mã:

import numpy.random as nprnd 
import heapq 
import sys 

sys.setrecursionlimit(10**6) 


def rlist(size, limit_low, limit_high): 
    for _ in xrange(size): 
     yield nprnd.randint(limit_low, limit_high) 

def iterator_mergesort(iterator, size): 
    return heapq.merge(
     iterator_mergesort(
      (iterator.__next__ for _ in xrange(size/2)), size/2), 
     iterator_mergesort(
      iterator, size - (size/2)) 
     ) 

def test(): 
    size = 10**3 
    randomiterator = rlist(size, 0, size) 
    sortediterator = iterator_mergesort(randomiterator, size) 
    assert sortediterator == sorted(randomiterator) 

if __name__ == '__main__': 
    test() 

Về cơ bản, nó chỉ là một mergesort hoạt động trên lặp và biểu thức máy phát điện thay vì làm việc trên danh sách để hạn chế tối đa bộ nhớ cùng một lúc . Nó không có gì đặc biệt và sử dụng phương thức tích hợp heapq.merge() để kết hợp các trình vòng lặp, vì vậy tôi đã rất ngạc nhiên khi mọi thứ bị hỏng.

Chạy mã nhanh chóng cung cấp Segmentation Fault: 11 và cửa sổ lỗi báo cho tôi biết python đã gặp sự cố. Tôi không có ý tưởng nơi để tìm hoặc làm thế nào để gỡ lỗi này, vì vậy bất kỳ trợ giúp sẽ được nhiều đánh giá cao.

+0

Thông thường, lần duy nhất bạn sẽ nhận được một segfault trong python là khi bạn ra khỏi bộ nhớ hoặc có một lỗi trong một trong các mô-đun C bạn đang sử dụng. [Câu hỏi này] (http://stackoverflow.com/questions/10035541/what-causes-a-python-segmentation-fault) có thể hữu ích cho bạn. – rnorris

+0

Ồ, tôi cảm thấy khá ngớ ngẩn, tôi quên dán một thùng cơ sở trong hộp trộn của tôi, vì vậy việc tăng giới hạn đệ quy sẽ phá vỡ mọi thứ. – reem

+3

@sortfiend - Nếu bạn phát hiện ra sự cố, bạn có thể viết nó như là một [câu trả lời ngắn và chấp nhận nó] (http://meta.stackoverflow.com/help/self-answer), thay vì sau đó chỉnh sửa tiêu đề thành nói "RESOLVED". Bằng cách đó, bài đăng này sẽ chơi đẹp hơn với các thuật toán của StackOverflow, và bạn có thể sẽ tích lũy thêm một vài upvotes ở đây và ở đó :) – Michael0x2a

Trả lời

6

Segmentation Faults trong python xảy ra vì một trong hai lý do:

Bạn chạy ra khỏi bộ nhớ

Bug trong một module C

Ở đây, lỗi seg thuộc về người đầu tiên. Bạn (I) có một đệ quy vô hạn vì không có trường hợp cơ sở trong iterator_mergesort(), nó sẽ tiếp tục tự gọi nó một cách vĩnh viễn và mãi mãi.

Thông thường, python ném một ngoại lệ cho điều này và nó sẽ chấm dứt trước khi gây ra một segfault. Tuy nhiên, giới hạn đệ quy đã được đặt cực kỳ cao nên python hết bộ nhớ và ngắt trước khi nó nhận ra nó nên ném một ngoại lệ cho một đệ quy không bị chặn.

Thêm một trường hợp cơ sở như vậy:

... 
def iterator_mergesort(iterator, size): 
return heapq.merge(
     iterator_mergesort(
      (iterator.next() for _ in xrange(size/2)), size/2), 
     iterator_mergesort(
      iterator, size - (size/2)) 
     ) if size >= 2 else iterator #<-- Specifically this 

Bây giờ nó vượt qua các chức năng và các loại test(), mặc dù khá chậm.