Russian Qt Forum

Программирование => С/C++ => Тема начата: Ovoshlook от Май 25, 2011, 09:33



Название: std::vector еще один вопрос
Отправлено: Ovoshlook от Май 25, 2011, 09:33
Здравствуйте. есть вопрос. В программе у меня имеется несколько векторов. До этого я с ними особо не работал но необходимость заставила.
Проблема заключается в следующем:
Векторы определяются как нулевые глобальные переменные. В одной из функция определяется их размер:
Код:
void OTS_MainWindow::AddTabForQuestion(QTabWidget *TabWidget)

{
    MainTabWidget       =new QWidget;
    MainTabVBoxLayout   =new QVBoxLayout;


    GlobalVaribles::NumberOfTab++;
    
    GlobalVaribles::SummOfTabAndTypeOfQuestionForCurrentTab.resize(GlobalVaribles::NumberOfTab);
    GlobalVaribles::NumberOfQuestionsCurrentTab.resize(GlobalVaribles::NumberOfTab);

    QString NumberOfTabForTabWidget=QString::number(GlobalVaribles::NumberOfTab);
    TabWidget->addTab(MainTabWidget,NumberOfTabForTabWidget);
    TabWidget->setCurrentWidget(MainTabWidget);
    TabWidget->currentWidget()->setLayout(MainTabVBoxLayout);

}

В следующей функции мне нужно записать значение в один из элементов вектора:
Код:
void OTS_MainWindow::AddVariantForSingleAnsverQuestion(QTabWidget *TabWidget)

{
   AnsverRadioButton= new QRadioButton;
   TextForAnsverContainer= new QTextEdit;
   RadioOrCheckButtonAndAnsverHBoxLayout=new QHBoxLayout;
   QVBoxLayout *Layout=static_cast<QVBoxLayout*>(TabWidget->currentWidget()->layout()->layout()->itemAt(1));

   GlobalVaribles::NumberOfQuestionsCurrentTab[TabWidget->currentIndex()]++;

   Layout->addLayout(RadioOrCheckButtonAndAnsverHBoxLayout);
   RadioOrCheckButtonAndAnsverHBoxLayout->addWidget(AnsverRadioButton,1);
   RadioOrCheckButtonAndAnsverHBoxLayout ->addWidget(TextForAnsverContainer,5);
}


собственно при выполнении последней функии программа завершается с кодом 0 но при этом закрывается крахом. Учитывая что при удалении операции увеличения элемента вектора она работает нормально я делаю вывод, что что то я с вектором неправильно делаю.

Прошу помощи, так как не совсем пойму, что и как у меня неправильно делается.
Заранее спасибо всем кто откликнулся.


Название: Re: std::vector
Отправлено: kambala от Май 25, 2011, 10:06
если у тебя элементы всегда записываются в конец вектора, то вместо resize() и operator[] лучше использовать push_back() (это так, на всякий случай)

может у тебя там банальный выход за границы массива? что дебаг говорит?

з.ы. а почему не QList? :)


Название: Re: std::vector
Отправлено: Пантер от Май 25, 2011, 10:12
з.ы. а почему не QList? :)
Тогда уж лучше QVector советуй.


Название: Re: std::vector
Отправлено: GreatSnake от Май 25, 2011, 10:36
з.ы. а почему не QList? :)
Тогда уж лучше QVector советуй.
Имхо, в данном случае абсолютно разницы нет :)

Цитата: cpp author=Ovoshlook
GlobalVaribles::GlobalVaribles::NumberOfQuestionsCurrentTab.resize(GlobalVaribles::NumberOfTab);
GlobalVaribles::NumberOfQuestionsCurrentTab[TabWidget->currentIndex()]++;
А ты случаем не разные вектора используешь?
И, имхо, очень трудно читабельный и перегруженный код, особенно члены класса с большой буквы.


Название: Re: std::vector
Отправлено: kambala от Май 25, 2011, 11:05
з.ы. а почему не QList? :)
Тогда уж лучше QVector советуй.
Цитата: assisstant
For most purposes, QList is the right class to use. Its index-based API is more convenient than QLinkedList's iterator-based API, and it is usually faster than QVector because of the way it stores its items in memory. It also expands to less code in your executable.


Название: Re: std::vector
Отправлено: Ovoshlook от Май 25, 2011, 12:09
resize я спользую чтобы переопределить размер вектора, чтобы он был равным количесву элементов, которые содержатся на widget (в данном случае количество табов). То есть после переопределения размеров количесво элементов в векторе значение которых равно 0 будет равно количеству табов. Далее на таб кладутся определенные элементы. Мне нужно подсчитать их количество, поэтому вместе с каждым положенным элементом я увеличиваю значение нужного мне элемента вектора на единицу. Вот примерно такая логика.


Название: Re: std::vector
Отправлено: Ovoshlook от Май 25, 2011, 12:10


может у тебя там банальный выход за границы массива? что дебаг говорит?

з.ы. а почему не QList? :)

Да вроде бы вектор мне подходит по своему описанию и по своим методам...

Дебаг вот что сказал:
Приложение остановлено, так как оно получило сигнал от операционной системы.

Сигнал:
SIGSEGV
Назначение:
Segmentation fault

GreatSnake
Не. Не разные. просто опечатался здесь. Это один вектор.

З.Ы. Еще вот чего надоумалось:
http://www.exdll.ru/stl-vektory/
Обращаться к элементам вектора можно по индексам. Значения индекса начинаются с нуля. Например, присвоить значение четвертому элементу объявленного выше вектора можно следующим образом:
Ints[3] = 15;
 Если первоначально зарезервированная память для элементов вектора исчерпана, число элементов вектора будет автоматически увеличено.

То есть получается что даже если моего элемента не сущесвовало то вектор увеличит память и создаст этот элемент. То есть выхода за пределы массива быть не должно. Поправьте если я не прав.


Название: Re: std::vector
Отправлено: kambala от Май 25, 2011, 14:27
а в трейсе что? в каком конкретно месте падает?

может у тебя в QTabWidget изначально уже есть один таб? тогда будет выход за границы вектора.


Название: Re: std::vector
Отправлено: Ovoshlook от Май 25, 2011, 14:29
а в трейсе что? в каком конкретно месте падает?

может у тебя в QTabWidget изначально уже есть один таб? тогда будет выход за границы вектора.
В том то и дело что в трейсе падает именно на GlobalVaribles::NumberOfQuestionsCurrentTab[TabWidget->currentIndex()]++;


Название: Re: std::vector
Отправлено: Пантер от Май 25, 2011, 14:29
То есть получается что даже если моего элемента не сущесвовало то вектор увеличит память и создаст этот элемент. То есть выхода за пределы массива быть не должно. Поправьте если я не прав.
Нет, это тебе не джава.


Название: Re: std::vector
Отправлено: Пантер от Май 25, 2011, 14:30
Ovoshlook, сделай вывод:
qDebug () << GlobalVaribles::NumberOfQuestionsCurrentTab.size () << TabWidget->currentIndex();
Перед этой строчкой.


Название: Re: std::vector
Отправлено: kambala от Май 25, 2011, 14:42
и кстати правильно не Ansver, а Answer


Название: Re: std::vector
Отправлено: Ovoshlook от Май 25, 2011, 14:44
По поводу джавы не на туда посмотрел. прошу прощения. Ну по поводу ansver- это моя безграмотность по английскому)
Добавил сточку. Действительно вектор нулевого размера( БУду смотреть .Спасибо за наводку. и за qDebug.

вопрос по qDebug(). Если не сложно отетьте пожалуйста. В одной функции он у меня выводит значение а в другой:
 qDebug()<< GlobalVaribles::NumberOfQuestionsCurrentTab.size()<<GlobalVaribles::NumberOfTab;

почему то ничего показывать не хочет. Может чего не так написал?


Название: Re: std::vector
Отправлено: Пантер от Май 25, 2011, 15:31
В консоль ничего не выводит? Сразу за этой строчкой падения не происходит? Вообще, попадает ли на эту строчку?


Название: Re: std::vector
Отправлено: Ovoshlook от Май 25, 2011, 15:58
Та стока которую вы привели работает нормально. по ней видно что размер вектора нулевой, и я пытаюсь обратиться к несуществующему элементу. поэтому программа и падает.
А по вопросу той строчки что я выписал (там последняя переменная для вывода в дебаг изменена), то эта строчка ничего в консоль не выводит к сожалению.


Название: Re: std::vector
Отправлено: Пантер от Май 25, 2011, 16:02
Странно, должна выводить....


Название: Re: std::vector
Отправлено: Ovoshlook от Май 25, 2011, 19:00
Я могу вам кинуть проект сам. Если не сложно посмотрите. Я не прошу за меня сделать, просто не пользовался дебагом, и по логике как вы правильно заметили должно выводитью Может что то не то написал все таки.
На всякий случай прикрепляю:

http://files.mail.ru/MOFBIN
После появления авторизационного окошка сразу ок жмите. Сточку я добавил в функцию OTS_MainWindow::AddTabForQuestion()

Заранее спасибо


Название: Re: std::vector
Отправлено: kambala от Май 25, 2011, 19:43
ничего не выводится потому, что туда программа и не заходит

строка 96:
Код
C++ (Qt)
if (QuestionTabWidget->currentIndex()==GlobalVaribles::NumberOfTab)
всегда будет выдавать ложь, поскольку когда нету табов, то индекс будет равен -1, а твое начальное значение GlobalVaribles::NumberOfTab равно 0. соответственно при каждом добавлении таба эти 2 величины всегда будут отличаться на 1. Установил начальное значение GlobalVaribles::NumberOfTab в -1 и все стало выводиться. раскомментировал тот инкремент и еще пару изменений вектора и закрашить приложение так и не удалось (на маке).

вскользь успел заметить, что форматирование кода немного хромает, правильно все-таки GlobalVariables и при добавлении таба, когда выделен непоследний таб, скачок значения происходит на 1 (напр. было 0 1, выделил 0 и нажал добавить - стало 0 2 3).


Название: Re: std::vector
Отправлено: Ovoshlook от Май 25, 2011, 21:58
ничего не выводится потому, что туда программа и не заходит

строка 96:
Код
C++ (Qt)
if (QuestionTabWidget->currentIndex()==GlobalVaribles::NumberOfTab)
всегда будет выдавать ложь, поскольку когда нету табов, то индекс будет равен -1, а твое начальное значение GlobalVaribles::NumberOfTab равно 0. соответственно при каждом добавлении таба эти 2 величины всегда будут отличаться на 1. Установил начальное значение GlobalVaribles::NumberOfTab в -1 и все стало выводиться. раскомментировал тот инкремент и еще пару изменений вектора и закрашить приложение так и не удалось (на маке).

вскользь успел заметить, что форматирование кода немного хромает, правильно все-таки GlobalVariables и при добавлении таба, когда выделен непоследний таб, скачок значения происходит на 1 (напр. было 0 1, выделил 0 и нажал добавить - стало 0 2 3).

Спасибо! Полгода программу не доставал мог и упустить)
Спасибо что указали на ошибки!
Ну а с английсим правописанием бедаа у меня))


Название: Re: std::vector еще один вопрос
Отправлено: Ovoshlook от Май 30, 2011, 09:25
Дабы не пложить тем у еня назрел еще один вопрос по вектору. на этот раз про дувмерный вектор.

Ситуация следующая:
Я создаю двумерный вектор (вектор векторов). По умолчанию он нулевой.
В нужный мне момент я определяю его размер:
Код:
vector.resize[k];
то есть по идее мой вектор сейчас состоит из k векторов размерности 0.

Собственно в один прекрасный момент мне требуется переопределить размер одного из векторов. каким образом мне это делать?

метод
Код:
vector[i].resize[j]

не работает. ругается ошибкой  при определении адреса перегруженной функции. Заранее определить размер векторов нельзя так как переопредеяется размер и заполняются элементы этих векторов динамически.

Сам вектор вроде правильно описываю :

Код:
static std::vector <std::vector<int> > vector;

Заранее всем спасибо за терпение и помощь.


Название: Re: std::vector еще один вопрос
Отправлено: kambala от Май 30, 2011, 09:53
Код
C++ (Qt)
#include <vector>
 
using std::vector;
 
int main()
{
vector<vector<int> > v;
v.resize(4);
v[2].resize(3);
return 0;
}
g++ компилирует без ошибок, размеры внешнего и внутренних векторов правильные

если у тебя элементы вектора заполняются последовательно, то лучше используй push_back(), чем resize()

з.ы. а тю, ты вызываешь resize[], а не resize() :)


Название: Re: std::vector еще один вопрос
Отправлено: Ovoshlook от Май 30, 2011, 11:50
Прошу прощения за свою невнимательность((( Написал вместо vector.resize(k) просто vector.resize