2014-07-20 14 views
1

我載體構建這樣的:C++載體插入訪問衝突讀取位置

struct segment { 
    float x1; 
    float y1; 
    float x2; 
    float y2; 
    float k; 
    float b; 
}; 

enum EventType {UPPER_PT = 0, LOWER_PT, INTER_PT}; 
struct order { 
    float x; 
    float y; 
    vector<segment>::iterator line_id; 
    vector<segment>::iterator line2_id; 
    EventType type; 
}; 

vector<segment> seg_lines; 
vector<order> event_list; 

初始化event_list後,我嘗試insert()隨機位置的新元素是這樣的:

order new_event; 
new_event.x = 300; 
new_event.y = 400; 
new_event.line_id = an_iterator_in_seg_lines; 
new_event.line2_id = another_iterator_in_seg_lines; 
new_event.type = INTER_PT; 

bool inte_inserted = false; 
for(vector<order>::iterator tmp_idx = event_list.begin(); tmp_idx != event_list.end(); tmp_idx++) { 
    if(a_Y_threshold > tmp_idx->y || a_Y_threshold == tmp_idx->y && an_X_threshold < tmp_idx->x) { 
     event_list.insert(tmp_idx, new_event); 
     inte_inserted = true; 
     break; 
    } 
} 

我可以向你保證line_idline2_id都是有效的。我只是想簡化我的描述。

在這種情況下,它試圖插入一個new_event在「5位」,而大小和event_list容量均爲10和event_list充滿了有效order

,但我得到這樣的錯誤:

Unhandled exception in ... 0xC0000005: Access violation reading location 0x00000000 

我認爲錯誤代碼告訴我,我使用的是無效的指針。但是我查看了'Watch'視圖,並且所有相關的迭代器(包括tmp_idx)都是有效的並指向正確的位置。

我嘗試使用emplace()而不是insert(),這是行不通的。在插入新元素之前,我嘗試了resize()我的event_list,但它也不起作用。但是當我使用list構建event_list,而不是vector,它就像一個魅力。

那麼,什麼可能導致此問題,如果我想堅持vector我應該怎麼辦?

我使用VS 2010

+4

插入(可能)引發新的分配和無效所有迭代器/指針 - 當你插入一個載體使用索引 –

+2

,則可能重新分配其緩衝區,導致所有迭代器到它變得無效。特別是'line_id'和'line2_id'無效可能是你的問題。使用'list'解決了這個問題,因爲迭代器不會因插入到列表而失效。 –

+3

您的代碼的可疑部分是您的訂單類的兩個迭代器。插入向量可能會導致迭代器失效。 – PaulMcKenzie

回答

1

cplusplus

If a reallocation happens, all iterators, pointers and references related to the container are invalidated.

,而在一個載體,它可能會使你的迭代循環要插入。 您可以將元素推回到矢量中而不是插入它們,並且只在最後對矢量重新排序。更容易和更清潔。

+0

後...和使用指標,而不是迭代器 – nishantjr

+0

迭代器是要走的路,它會更容易從一個STL容器切換到另一個。 –