Форум программистов, компьютерный форум CyberForum.ru

Двумерынй вектор, удаление через erase - C++

Восстановить пароль Регистрация
 
Stille
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 5
31.08.2012, 13:17     Двумерынй вектор, удаление через erase #1
Есть двумерный вектор Clusters:
std::vector <std::vector <int> > Clusters (ExternalSetV.size(), std::vector <int> (1));
Изначально размер строк 1, потом может увеличиваться. После определенных действий нужно удалить строку из вектора, использую: Clusters.erase(Clusters.begin() + X);
Это все происходит в цикле по размеру вектора Clusters: while (Clusters.size() > Y).
Весь процесс итерационный и выполняется 100 раз (каждый раз вектор Clusters создается заново, с новым размером). На какой-то из итераций (может вылететь на первой, может на сотой) вылетает ошибка доступа: Access violation at adress 004085C6 in module 'Project1.exe'. Read of address 438C9618. И выкидывает на строку из библиотеки вектора:
iterator begin() { return this->_M_start; }
В чем может быть дело?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.08.2012, 13:17     Двумерынй вектор, удаление через erase
Посмотрите здесь:

массивы через вектор C++
C++ vector.erase
.erase() в массиве. C++
C++ vector::erase()?
Двумерный массив через вектор C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
novi4ok
549 / 502 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
31.08.2012, 13:21     Двумерынй вектор, удаление через erase #2
покажи код
Stille
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 5
31.08.2012, 13:25  [ТС]     Двумерынй вектор, удаление через erase #3
C++
1
2
3
4
5
6
7
8
9
std::vector <std::vector <int> > Clusters (ExternalSetV.size(), std::vector <int> (1));
...
for (int i=0 ; i<ExternalSetV.size() ; i++)
                Clusters[i][0] = i;
while (Clusters.size() > ExternalSetSize)
        {
        Всякие действия по выяснению того, какую строку удалять
        Clusters.erase(Clusters.begin() + Minj);
        }
novi4ok
549 / 502 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
31.08.2012, 13:37     Двумерынй вектор, удаление через erase #4
откуда берется Minj?
перепиши так:
C++
1
2
3
4
5
if (Clusters.size() > Minj){
   Clusters.erase(Clusters.begin() + Minj);
} else {
   // покажи оба значения: Clusters.size() & Minj
}
Stille
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 5
31.08.2012, 13:41  [ТС]     Двумерынй вектор, удаление через erase #5
Цитата Сообщение от novi4ok Посмотреть сообщение
откуда берется Minj?
перепиши так:
C++
1
2
3
4
5
if (Clusters.size() > Minj){
   Clusters.erase(Clusters.begin() + Minj);
} else {
   // покажи оба значения: Clusters.size() & Minj
}
Minj получается путем долгих манипуляций, но она выясняется в цикле, ограниченному по Clusters.size():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                double Min;
                int Mini, Minj;
                Min = Distances[0][1];
                for (int i=0 ; i<Clusters.size() ; i++)
                {
                        for (int j=0 ; j<Clusters.size() ; j++)
                        {
                                if (i != j)
                                {
                                        if (Min > Distances[i][j])
                                        {
                                                Min = Distances[i][j];
                                                Mini = i;
                                                Minj = j;
                                        }
                                }
                        }
                }
novi4ok
549 / 502 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
31.08.2012, 19:30     Двумерынй вектор, удаление через erase #6
вроде получается, что Minj не может быть меньше размера вектора, но ты попробуй написать как я предложил, и вылови эту ситуацию. или в отладчике посмотри call stack в момент, когда вылетает эта ситуация. или приведи весь код полностью, я попробую воспроизвести. можно, конечно, чисто мозговыми усилиями дойти, но это - если удовольствие доставляет. а если быстро причину нужно найти - мой путь быстрее.
Stille
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 5
31.08.2012, 19:58  [ТС]     Двумерынй вектор, удаление через erase #7
Цитата Сообщение от novi4ok Посмотреть сообщение
вроде получается, что Minj не может быть меньше размера вектора, но ты попробуй написать как я предложил, и вылови эту ситуацию. или в отладчике посмотри call stack в момент, когда вылетает эта ситуация. или приведи весь код полностью, я попробую воспроизвести. можно, конечно, чисто мозговыми усилиями дойти, но это - если удовольствие доставляет. а если быстро причину нужно найти - мой путь быстрее.
Я пробовал так, как ты написал, ничего не изменилось, т.к. он никогда и не был меньше размера вектора. Я сделал чуть по другому:
вместо
C++
1
Clusters.erase(Clusters.begin() + Minj);
написал
C++
1
Clusters.erase(Clusters.end() - 1 - (Clusters.size() - Minj));
и, по какой-то неизвестной мне причине, ошибки стали вылетать реже. Не исчезли совсем, но реже и уже на другую строчку библиотеки вектора:
C++
1
size_type size() const        { return size_type(this->_M_finish - this->_M_start); }
Поищу еще проблему, если не найду, то перепишу всю функцию. Но, используя Clusters.end(), он хотя бы иногда (где-то в 30% случаев) проходит все 100 итераций без вылетов
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
31.08.2012, 21:43     Двумерынй вектор, удаление через erase #8
Цитата Сообщение от Stille Посмотреть сообщение
Minj получается путем долгих манипуляций, но она выясняется в цикле, ограниченному по Clusters.size()
Mini и Minj не инициализируются. Если Distances[0][1] является минимумом, то эти переменные так и останутся неинициализированными.
Цитата Сообщение от Stille Посмотреть сообщение
Я пробовал так, как ты написал, ничего не изменилось, т.к. он никогда и не был меньше размера вектора. Я сделал чуть по другому:
вместо
C++
1
Clusters.erase(Clusters.begin() + Minj);
написал
C++
1
Clusters.erase(Clusters.end() - 1 - (Clusters.size() - Minj));
Эти строки не эквивалентны. Если Minj == 0, то вторая приведёт к ошибке. Первая приводит к ошибке если Minj >= Clusters.size(), но в целом первый вариант внушает больше доверия.
В общем, проверяй значения Minj и смотри при каких возникает ошибка.
Stille
0 / 0 / 0
Регистрация: 31.08.2012
Сообщений: 5
31.08.2012, 22:07  [ТС]     Двумерынй вектор, удаление через erase #9
Цитата Сообщение от grizlik78 Посмотреть сообщение
Mini и Minj не инициализируются. Если Distances[0][1] является минимумом, то эти переменные так и останутся неинициализированными.
Блин Вот это упущение! Это все и объясняет! Сейчас прогнал алгоритм 10 раз (по 100 итераций каждый) - ни одного вылета! Я уж было разочаровался в векторах Спасибо огромное!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.09.2012, 01:33     Двумерынй вектор, удаление через erase
Еще ссылки по теме:

C++ вектор алгоритм erase
Шаблон класса вектор с операциями индексации и функциями insert и erase C++
C++ Вывести вектор через messagebox

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
novi4ok
549 / 502 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
01.09.2012, 01:33     Двумерынй вектор, удаление через erase #10
grizlik78, респект! это тот случай, когда головой. мне проще компьютером.
Yandex
Объявления
01.09.2012, 01:33     Двумерынй вектор, удаление через erase
Ответ Создать тему
Опции темы

Текущее время: 03:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru