Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Странная проблема с использованием vector, Странная проблема с vector 
:(
    Опции темы
gAlexKo
Дата 16.1.2015, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 23.3.2011

Репутация: нет
Всего: нет



В упрощенном виде проблема такая. Я создаю вектор (vector) из четырех списков. Каждый список это поле индекса для сортировки и сам список в виде TStringList. После сортировки вектора два последних элемента пропадают, например обращение по индексу 3 вызывает ошибку выхода за пределы TStringList (List index out of bounds). Вот упрощенный код проблемы, посмотрите пожалуйста. Я компилировал это как консольное приложение CBuilder 6.

#include <stdio.h>
#include <vector>
#include <Classes.hpp>
#include <algorithm>
using namespace std;

struct SPISOK_STRUCT
{
int sorting_field;             //по этому полю будет сортировка
TStringList *spisok;

    SPISOK_STRUCT(void)  { sorting_field=0; spisok = new TStringList; }
    ~SPISOK_STRUCT(void) { delete spisok; spisok=NULL; }
    SPISOK_STRUCT(const SPISOK_STRUCT& x)
    {
      spisok = new TStringList;
      sorting_field = x.sorting_field;
      for(int i=0; i < x.spisok->Count; i++)
         spisok->Add(x.spisok->Strings[i]);
    }

    SPISOK_STRUCT& operator= (const SPISOK_STRUCT& x)
    {
      sorting_field = x.sorting_field;
        spisok->Clear();
        for(int i=0; i < x.spisok->Count; i++)
          spisok->Add(x.spisok->Strings[i]);
      return *this;
    }

   friend bool operator< (const SPISOK_STRUCT &x, const SPISOK_STRUCT &y)
   {
      bool ret = (x.sorting_field < y.sorting_field);
      return ret;
   }
};

/*---------------------------------------------*/
int main(int argc, char* argv[])
{
AnsiString astr;
vector<SPISOK_STRUCT> spiski;  //вектор списков

   spiski.clear();
   for(int i=1; i<=4; i++)  //делаем 4 списка по 2 строки в каждом
     {
     SPISOK_STRUCT x;
        for(int j=1; j < 3; j++)
         {
          AnsiString astr = AnsiString("spisok N'") + i + " line" + j;
          x.spisok->Add(astr);
         }

     x.sorting_field = i;
     spiski.insert(spiski.end(), x);
     }

     //тестовый вывод строки из 4-го списка
astr = spiski[3].spisok->Strings[0];
printf("stable_sort1: %s\n", astr.c_str());

 stable_sort(spiski.begin(), spiski.end());
     //тестовый вывод строки из 4-го списка
astr = spiski[3].spisok->Strings[0];
printf("stable_sort2: %s\n", astr.c_str());

return 0;
}
/*------------------------------------------*/


Это сообщение отредактировал(а) gAlexKo - 16.1.2015, 13:21
PM MAIL   Вверх
borisbn
Дата 30.1.2015, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Вроде всё работает как надо - http://ideone.com/5NdPXN
Ты уверен, что проблема не в "боевой" программе, а и в приведённом тобой упрощённом примере тоже ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gAlexKo
Дата 30.1.2015, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 23.3.2011

Репутация: нет
Всего: нет



Цитата(borisbn @ 30.1.2015,  10:08)
Вроде всё работает как надо - http://ideone.com/5NdPXN
Ты уверен, что проблема не в "боевой" программе, а и в приведённом тобой упрощённом примере тоже ?

Да, проверил еще раз. Возможно ты не заметил - это на самом деле не заметно в консольном режиме - программа вылетает без сообщений.  Попробуй поставить break на return. Нужно увидеть результат от
printf("stable_sort2: %s\n", astr.c_str());

Если у тебя есть CBuilder6, то вот полный консольный проект (см архив).

PS: Между прочим если заметить stable_sort на sort, то работает. 

Это сообщение отредактировал(а) gAlexKo - 30.1.2015, 13:37

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  test_concole.zip 2,93 Kb
PM MAIL   Вверх
borisbn
Дата 30.1.2015, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Проблема в том, что в операторе присваивания ты не проверяешь, что присваивают объект самому себе.
Добавь в начало SPISOK_STRUCT& operator= (const SPISOK_STRUCT& x) такие строчки 
Код
      if ( &x == this ) {
        int bp = 0;
        return *this;
      }

и поставь breakpoint на int bp = 0;.
На IdeOne этого не происходит, т.к. там другая реализация stable_sort.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gAlexKo
Дата 2.2.2015, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 23.3.2011

Репутация: нет
Всего: нет



Цитата(borisbn @ 30.1.2015,  14:36)
Проблема в том, что в операторе присваивания ты не проверяешь, что присваивают объект самому себе.
Добавь в начало SPISOK_STRUCT& operator= (const SPISOK_STRUCT& x) такие строчки 
Код
      if ( &x == this ) {
        int bp = 0;
        return *this;
      }

и поставь breakpoint на int bp = 0;.
На IdeOne этого не происходит, т.к. там другая реализация stable_sort.

Да, действительно, спасибо! Честно говоря как-то всегда делал операторы равно без такого анализа и вроде все обходилось. Все работает, даже без " int bp = 0; smile
PM MAIL   Вверх
feodorv
Дата 2.2.2015, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(gAlexKo @  2.2.2015,  10:38 Найти цитируемый пост)
даже без " int bp = 0;

Так ведь это только для
Цитата(borisbn @  30.1.2015,  14:36 Найти цитируемый пост)
поставь breakpoint на int bp = 0;

А так это не нужно.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1054 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.