2016-08-21 2 views
1

В нашем коде мы используем контейнеры stl и MFC. Я столкнулся с случаем, когда у нас есть объект CArray, где каждый объект содержит std :: vector.std :: vector внутри MFC CArray - получение ошибки «итератор не реверсифицируемой» после добавления элементов в CArray

После добавления нескольких объектов в CArray, чтобы данные в CArray были перераспределены и скопированы, когда достигнет максимального размера, кажется, что внутренний вектор поврежден. Когда я перебираю CArray и каждый объект перебирает std :: vector, я получаю ошибку «векторный итератор, а не реверсифицируемый».

Я просмотрел код MFC и использует memcpy() для копирования данных после перераспределения. В std :: vector (я использую визуальную студию) есть член, называемый _Myproxy, который имеет член, называемый _Mycont, который, кажется, меняет его значение в новом векторе (вектор, который был скопирован memcpy()).

Я воспроизвел эту проблему, я прилагаю пример кода ниже.

Я могу реорганизовать этот код, и я, вероятно, сделаю это, но я хочу точно понять, что происходит.

#include "stdafx.h" 

#include <vector> 
#include <iostream> 

// an object which holds an std::vector 
class test_t 
{ 
public: 
    test_t() {} 

    ~test_t() 
    { 
     std::cout << "d'tor" << std::endl; 
    } 

    void add(int i) 
    { 
     m_vec.push_back(i); 
    } 

    void print() 
    { 
     for (std::vector<int>::iterator it = m_vec.begin(); it != m_vec.end(); ++it) 
     { 
      int i = *it; 
      std::cout << i << std::endl; 
     } 

     std::cout << std::endl; 
    } 

private: 
    std::vector<int> m_vec; 
}; 

void test() 
{ 
    // array if objects where each object holds an std::vector 
    CArray<test_t, test_t&> arr; 

    for (int i = 0; i < 10; ++i) 
    { 
     test_t t; 
     int j = arr.Add(t); 
     test_t& rt = arr[i]; 
     rt.add(1); 
     rt.add(2); 
     rt.add(3); 
    } 

    for (int i = 0; i < arr.GetSize(); ++i) 
    { 
     test_t& rt = arr[i]; 
     rt.print(); // error occurs here 
    } 
} 

Спасибо, Gabriel

ответ

6

CArray оленья кожа хорошо играть с типами не-POD, опираясь на memcpy_s при изменении размера. You может заставить его работать, но в целом его лучше избегать для этого случая использования.

См. Примечание: https://msdn.microsoft.com/en-us/library/4h2f09ct.aspx