OCCI - setDataBuffer + vector ‹struct›

Попытка минимизировать количество строк для выборки массива OCCI путем сохранения структуры, содержащей буфер символов, в вектор, код ниже:

    struct Columns { char buffer[1000][300]; };

    int i = 1;
    Columns col;
    ub4* ub = NULL;
    results->setDataBuffer( i++, col.buffer, OCCI_SQLT_STR, sizeof( col.buffer[ 0 ] ), ub );
        vec.push_back( col );

    cout << "Before, vec size: " << vec.size( ) << "\n"; // prints 1, as expected
    while ( results->next( 1000 ) ) {
        for ( size_t j = 0; j < results->getNumArrayRows( ); ++j ) {
            cout << vec[ 0 ].buffer[ j ] << endl;
        }

Теперь почему-то это не работает. Однако, если вместо использования col.buffer я создаю буфер символов [1000] [300] и помещаю его в setDataBuffer, тогда в части cout выполните: cout ‹* buffer [j] ‹< endl;

это прекрасно работает. Так что я не совсем уверен, где я облажался?

буфер символов - это то же самое, что и col.buffer, не так ли?

Я не думаю, что это имеет значение, но структура столбцов определена в файле заголовка.


person user1324674    schedule 06.07.2017    source источник


Ответы (1)


Я предполагаю, что setDataBuffer заполняет буфер, который вы передаете в качестве параметра (который здесь col.buffer), затем вы вставляете его в вектор, поэтому новый struct Columns выделяется vec и копирует содержимое col. Теперь col и vec[0] - два разных объекта.

Затем вы вызываете некоторые методы, которые заполняют буфер, который вы ему впервые передали. Таким образом, он заполняет col.buffer, и вы читаете vec[0].buffer, которые разные, потому что это 2 разных объекта.

Вместо этого можно было бы сделать vec.emplace_back(); для создания одного экземпляра, а затем передать vec[0].buffer setDataBuffer. Но будьте осторожны с адресами элементов в векторах. Если вы измените вектор (добавив или удалив элементы), он может перераспределить его содержимое, и адреса элементов могут измениться.

person Ludonope    schedule 07.07.2017
comment
То есть push_back не копирует содержимое буфера символов? Это сбивает с толку, в документации говорится, что он копирует, подумал, что скопирует все. Однако решение emplace_back сработало, спасибо. - person user1324674; 07.07.2017
comment
Ну, он копирует его, но как только он копируется, это другой объект, только с идентичным содержанием. Возможно, вы использовали другой язык, например C # для JS, который по умолчанию использует объект в качестве ссылки. Это означает, что если вы сделаете копию объекта a с именем b и измените b, содержимое a также изменится. Если вам нужна настоящая копия, вам нужно ее клонировать. В C / C ++ все по-другому, по умолчанию используются значения. Это означает, что если вы делаете a = b, a является клоном b, если вы изменяете один из них, другой не изменяется (если вы явно не определили a как ссылку, например int &a = b;) - person Ludonope; 07.07.2017
comment
Так что же именно происходит? Оригинал выходит за рамки / заменяется, затем пуф, данные пропали? Однако использование вектора, похоже, не работает с функцией setdatabuffer. Я не совсем понимаю, почему, вы случайно не знаете? Он работает с 1 столбцом, но если столбцов больше 1, он вылетает. - person user1324674; 08.07.2017
comment
Я не совсем уверен, почему он вылетает с более чем одним столбцом, но как только вы вернете col в vec, col и vec станут двумя разными объектами. Они оба существуют. Но поскольку вы передали col.buffer и скопировали содержимое col в vec[0] перед обновлением содержимого буфера (что, я думаю, именно то, что делает results->next, изменяется только col.buffer, поэтому vec[0] вообще не меняется. Надеюсь, я помог, скажите мне, если вы есть еще вопросы - person Ludonope; 08.07.2017