Russian Qt Forum
Ноябрь 23, 2024, 17:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: stl контейнер и указатели  (Прочитано 6867 раз)
sidsukana
Гость
« : Апрель 20, 2012, 11:54 »

Добрый день. Есть такая проблемка, нуждаюсь в помощи матерых Улыбающийся
Имееются векторы структур в векторе

Код
C++ (Qt)
struct Cell
{
   union
   {
       uint32 u;
       int32 i;
       float f;
       char* s;
   }
};
vector<vector<Cell>> dataTable;

Данные в ячейке всегда в первых 3 типах, а char* нужен чтобы отдельно потом туда положить указатель на строку.

Вот пример. Допустим в 3 поле мне надо положить строку из другого вектора с помощью указателя.

Код
C++ (Qt)
 
vector<string> strings("123", "456", "789");
 
vector<Cell> v = dataTable.at(0);
v[2].s = (char*)strings.at(0).c_str();
// Теперь если смотреть в отладке в v[2].s содержится "123"

Далее, я хочу в 5 ячейку также поместить другую строку

Код
C++ (Qt)
v[4].s = (char*)strings.at(1).c_str();
// Смотрим в отладке - видим что v[2].s теперь стало "456", а указатели абсолютно одинаковые.

Объясните мне эту соль в С++ ,а то не докуриваю что не так и почему так происходит))
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Апрель 20, 2012, 12:27 »

Впечатление что Вы приводите текст "для примера" - а ответ нужен конкретный  Улыбающийся
Код
C++ (Qt)
vector<string> strings("123", "456", "789");
 
Не знаю такого конструктора вектора

Если Вы почистите код и будете использовать const как положено - то вероятно само и рассосется  Улыбающийся
Записан
mutineer
Гость
« Ответ #2 : Апрель 20, 2012, 12:31 »

Цитировать
The returned array points to an internal location with the required storage space for this sequence of characters plus its terminating null-character, but the values in this array should not be modified in the program and are only guaranteed to remain unchanged until the next call to a non-constant member function of the string object.

Не стоит сохранять вернувшийся из c_str указатель, так как содержимое этой области памяти может измениться
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Апрель 20, 2012, 12:59 »

Не стоит сохранять вернувшийся из c_str указатель, так как содержимое этой области памяти может измениться
Ну если нет никаких модификаций - то чего ему меняться? Но зачем городить вектор <std::string> если эти строки все равно "только чтение"? Просто так
Код
C++ (Qt)
const char * theStrings[] = { "123", "456", "789" };
 
Записан
sidsukana
Гость
« Ответ #4 : Апрель 20, 2012, 13:05 »

Впечатление что Вы приводите текст "для примера" - а ответ нужен конкретный  Улыбающийся
Код
C++ (Qt)
vector<string> strings("123", "456", "789");
 
Не знаю такого конструктора вектора

Если Вы почистите код и будете использовать const как положено - то вероятно само и рассосется  Улыбающийся
Ну создание вектора таким образом я для примера написал)) весь код дома к сожалению, а сейчас на работе) Но я думаю вы поняли что я имел ввиду вектор из 3 элементов))
« Последнее редактирование: Апрель 20, 2012, 13:07 от sidsukana » Записан
sidsukana
Гость
« Ответ #5 : Апрель 20, 2012, 13:06 »

Не стоит сохранять вернувшийся из c_str указатель, так как содержимое этой области памяти может измениться
Ну если нет никаких модификаций - то чего ему меняться? Но зачем городить вектор <std::string> если эти строки все равно "только чтение"? Просто так
Код
C++ (Qt)
const char * theStrings[] = { "123", "456", "789" };
 

Нет, массив должен быть динамический. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Апрель 20, 2012, 13:14 »

Нет, массив должен быть динамический. Улыбающийся
Тогда никак не вектор, потому что у него адреса элементов уплывают при добавлении новых элементов - причем не всякий раз, а подленько. Используйте напр std::list или std;;dequeu

И const все-таки лучше писать, а то ужасная анти-санитария
Записан
sidsukana
Гость
« Ответ #7 : Апрель 20, 2012, 13:39 »

Ну я заполняю массив заранее и в дальнейшем его уже не меняю. Заполняю его из файла. Поэтому динамический.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Апрель 20, 2012, 16:14 »

Ну я заполняю массив заранее и в дальнейшем его уже не меняю. Заполняю его из файла. Поэтому динамический.
Вместо того чтобы пререкаться "меняю- не меняю" просто используйте более подходящий контейнер. А потом поговорим
Записан
V1KT0P
Гость
« Ответ #9 : Апрель 20, 2012, 16:24 »

Прочитал комментарии и ничего не понял =). Что хочет автор? Если получить массив чаров из кьюстринга, то вот решение:
Код
C++ (Qt)
char* charFromQString(QString &str)
{
   char *tmp = new char[str.length()+1];
   strncpy(tmp, str.toLocal8Bit(), str.length());
   tmp[str.length()] = 0;
   return tmp;
}
 
v[2].s = charFromQString(strings.at(0));
Записан
sidsukana
Гость
« Ответ #10 : Апрель 20, 2012, 17:53 »

Помоему все ясно я написал - надо указатель на строку поместить в указатель что находится в структуре, которая является элементом массива.
Записан
V1KT0P
Гость
« Ответ #11 : Апрель 20, 2012, 18:23 »

Помоему все ясно я написал - надо указатель на строку поместить в указатель что находится в структуре, которая является элементом массива.
Блин не заметил что про стандартные стринги написано, тогда так:
Код
C++ (Qt)
char* charFromString(string &str)
{
   char *tmp = new char[str.length()+1];
   strncpy(tmp, str.c_str(), str.length());
   tmp[str.length()] = 0;
   return tmp;
}
Либо храни указатель не на чар а на стринг раз тебе только чтение необходимо. Никогда в жизни даже не думал хранить указатель на буфер чаров выданный каким-либо стринговым классом, ибо может много плохого случиться.
« Последнее редактирование: Апрель 20, 2012, 18:29 от V1KT0P » Записан
sidsukana
Гость
« Ответ #12 : Апрель 20, 2012, 18:55 »

Все проблему решил. В структуре Cell сделал указатель константным и без приведения типа присвоил его. Однако пришлось вектор тоже через pointer достать.

В общем вот так получилось у меня

Код
C++ (Qt)
template<typename T>
T* File::getRecord(uint32 id) const
{
   vector<vector<Cell>>::pointer v = getRecord(id);
 
   for (vector<uint32>::iterator itr = m_stringFields.begin(); itr != m_stringFields.end(); ++itr)
   {
       Cell* cell = &v->at(*itr);
       const char* str = m_stringsBlock.at(cell->u).c_str();
       cell->s = str;
   }
 
   return (T*)v->data();
}
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.275 секунд. Запросов: 22.