2010-10-27 43 views
5

Tôi đã cố gắng chuyển đổi dự án vc7.1 thành vs2010 mà tôi nhận được từ codeproject. (Và đây là liên kết h tt p: //www.codeproject.com/KB/cpp/transactions.aspx? Fid = 11253 & df = 90 & MPP = 50 & tiếng ồn = 3 & sort = Chức & view = Mở rộng & fr = 1 # xx0xxVị trí mới có gọi hàm tạo nếu con trỏ được truyền là null không?

Nhưng sau khi được chuyển đổi và điều chỉnh cấu hình của nó.

tôi thấy nó debug không thành công, nó nói Unhandled ngoại lệ tại 0x0028e7b9 trong DrawIt.exe: 0xC0000005: Vi phạm quyền truy cập ghi vị trí 0x00000000.

Dòng lỗi đi như thế này

data = new(Mm::Allocate(sizeof(DocData), sid)) DocData(); 

Và chức năng

void* Allocate(size_t size, SPACEID sid) 
{ 
    AUDIT 

    Spaces::iterator s = spaces.find(sid); 
    if (s == spaces.end()) 
     return NULL; 

    Space& space = s->second; 
    if (!space.transacting) 
     return NULL; 

    size = max(size, sizeof(Free)); 

    // TODO: assert that "data" is allocated in space 
    space.AssertData(); 

    // are there any more free chunks? 
    if (!space.data->sFreeHead) { 
     space.data->Insert(space.More(size)); 
    } 

    AUDIT 

    // find the first chunk at least the size requested 
    Free* prev = 0; 
    Free* f = space.data->sFreeHead; 
    while (f && (f->size < size)) { 
     prev = f; 
     f = f->next; 
    } 

    AUDIT 
    // if we found one, disconnect it 
    if (f) { 
     space.data->locTree.remove((size_t)f); 

     if (prev) prev->next = f->next; 
     else space.data->sFreeHead = f->next; 

     f->next = 0; 
     memset(&f->loc, 0, sizeof(f->loc)); 
    } else { 
     f = space.More(size); 
    } 

    // f is disconnected from the free list at this point 

    AUDIT 

    // if the free chunk is too(?) big, carve a peice off and return 
    // the rest to the free list 
    if (f->size > (2*(size + sizeof(Free)))) { 
     Free* tmp = space.data->Slice(f, size); // slice size byte off 'f' 
     space.data->Insert(f); // return the remainder to the free list 
     f = tmp; 
    } 

    AUDIT 

    CHECK_POINTER(f) 

    void* p = reinterpret_cast<void*>((char*)f + sizeof(Free::SIZE_TYPE)); 

    CHECK_POINTER(p) 

    return p; 
} 

Bất cứ ai có ý tưởng, plz?

Vì tôi không giỏi ở C++, sẽ mất một thời gian trước khi tôi tìm ra cách giải quyết vấn đề này. Chỉ cần tải lên mã nguồn source file, nó sẽ được đánh giá cao nếu ai đó có thể trợ giúp.

+0

Đây là một câu hỏi thực sự tốt có thể được đặt lại trong các thuật ngữ ngắn hơn như sau: * Vị trí mới có gọi hàm khởi tạo nếu con trỏ được truyền không null? * –

Trả lời

2

Vâng, chức năng Allocate của bạn đang trở lại rõ ràng NULL. Thật khó cho chúng tôi để nói ở đâu và tại sao, và nó là tầm thường cho bạn để thiết lập các điểm ngắt và bước qua bản phân bổ chính mình, vì vậy tôi đề nghị bạn làm điều đó và tìm ra nơi hàm trả về.

+0

Nó trả về một con trỏ nào đó ... Sau void * p = reinterpret_cast ((char *) f + sizeof (Miễn phí :: SIZE_TYPE)); – WhiteTopaz

4

[Câu trả lời này có thể sai; xem các bình luận để thảo luận; Tôi sẽ để lại điều này cho đến lúc này để chúng tôi có thể tìm ra câu trả lời là gì]

Allocate trả về NULL trong một số trường hợp lỗi.

Bạn không kiểm tra kết quả của việc gọi Allocate trước khi sử dụng.

Bạn cần kiểm tra kết quả. Ngoài ra, bạn có thể ném một ngoại lệ khi bạn có một thất bại.

+0

Cảm ơn, tôi sẽ xem liệu tôi có thể khắc phục được không. – WhiteTopaz

+0

Nhưng P không phải là Null khi nó trả về, nó trả về 0x0042ffd8? – WhiteTopaz

+0

Bạn có thực sự cần phải kiểm tra null trước khi gọi vị trí mới không? Tôi đã không thể xác định điều này từ tiêu chuẩn. Ở một bên, có vẻ hợp lý để làm, mặt khác, gọi là không ném mới ngụ ý rằng người cấp phát có thể trả về 0, và việc xây dựng vị trí sau này phải được bỏ qua ... Tôi cảm nhận được vị trí mới * có thể * được gọi trên một con trỏ null, nhưng không có tham chiếu rõ ràng từ tiêu chuẩn. Nó cũng có thể được xử lý bởi 'new (std :: nothrow)' thực hiện kiểm tra * trước khi * gọi vị trí mới. BTW, g ++ 4.2.1: 'new (0) test;' không gọi hàm tạo, cũng không chết. –

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