memcpy
От: SmileIlya  
Дата: 15.04.15 14:19
Оценка: -3 :)
Доброго всем дня.
Есть проблема, кусок кода ниже.
Суть проблемы в том, что при вызове memcpy приложение схлопывается, ругаясь на ошибку чтения.

Необработанное исключение в "0x5cddc9c7 (msvcr100d.dll)" в "Test.exe": 0xC0000005: Нарушение прав доступа при чтении "0x115d0000".

std::vector<double> vDouble;
for (UINT i = 0; i < 1000; i++)
{
  double dID = i;
  vDouble.push_back(dID );
}

const void* pValue = &vDouble;

size_t nBytes = sizeof(vector<void*>) + (sizeof(void*) * (static_cast<vector<void*> const*>( pValue ))->size());
size_t    nValueBytes = 0;
void*    pValuePoint = NULL;

if(!pValue || !nBytes)
    return NULL;

if(!pValuePoint)
    pValuePoint = malloc(nBytes);
else
    if(nValueBytes != nBytes)
        pValuePoint = realloc(pValuePoint, nBytes);

if(!pValuePoint)
    return NULL;

nValueBytes = nBytes;
memcpy(pValuePoint, pValue, nValueBytes); // проблема тут
Re[7]: memcpy
От: Stanislav V. Zudin Россия  
Дата: 15.04.15 17:14
Оценка: 3 (1) +1
Здравствуйте, SmileIlya, Вы писали:

SI>может я чего-то не понимаю, но как вернуть вектор после всех преобразований?


Гм, допустим ты скопировал свой вектор и у тебя есть твои pValuePoint с массивом байт и nValueBytes с числом этих самых байт.

Если передается только полезный груз без служебной информации, то вот так:
std::vector<double> another_vDouble;                   // твой приготовленный массив, куда надо скопировать данные

size_t sz = nValueBytes / sizeof(double);              // число даблов в "посылке"
another_vDouble.resize(sz);                            // выделить память под данные
memcpy(&another_vDouble[0], pValuePoint, nValueBytes); // скопировать "посылку" в массив
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: memcpy
От: _DAle_ Беларусь  
Дата: 15.04.15 14:51
Оценка: :)
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Я правильно понимаю, что ты хочешь скопировать данные, лежащие в массиве?


Да нет, ты не понял, он хочет "нормально скопировать pValuePoint значение"
Re: memcpy
От: ononim  
Дата: 15.04.15 19:12
Оценка: +1
SI>
SI>std::vector<double> vDouble;
SI>for (UINT i = 0; i < 1000; i++)
SI>{
SI>  double dID = i;
SI>  vDouble.push_back(dID );
SI>}
SI>const void* pValue = &vDouble;
SI>


полагаю тут имелось ввиду
const void* pValue = &vDouble[0];

дальше не смотрел, но судя по коментам там тоже не все гладко
Как много веселых ребят, и все делают велосипед...
Re: memcpy
От: _DAle_ Беларусь  
Дата: 15.04.15 14:29
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>Необработанное исключение в "0x5cddc9c7 (msvcr100d.dll)" в "Test.exe": 0xC0000005: Нарушение прав доступа при чтении "0x115d0000".


SI>
SI>...
SI>memcpy(pValuePoint, pValue, nValueBytes); // проблема тут
SI>


Ты почему то решил, что можешь скопировать nValueBytes. Из каких соображений можно только догадываться. Это типа лежат в памяти дата-мемберы вектора, а потом сам массив с числами? Это не так.
Re: memcpy
От: Stanislav V. Zudin Россия  
Дата: 15.04.15 14:29
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>Доброго всем дня.

SI>Есть проблема, кусок кода ниже.
SI>Суть проблемы в том, что при вызове memcpy приложение схлопывается, ругаясь на ошибку чтения.

SI>Необработанное исключение в "0x5cddc9c7 (msvcr100d.dll)" в "Test.exe": 0xC0000005: Нарушение прав доступа при чтении "0x115d0000".

  Жуть какая
SI>
SI>std::vector<double> vDouble;
SI>for (UINT i = 0; i < 1000; i++)
SI>{
SI>  double dID = i;
SI>  vDouble.push_back(dID );
SI>}

SI>const void* pValue = &vDouble;

SI>size_t nBytes = sizeof(vector<void*>) + (sizeof(void*) * (static_cast<vector<void*> const*>( pValue ))->size());
SI>size_t    nValueBytes = 0;
SI>void*    pValuePoint = NULL;

SI>if(!pValue || !nBytes)
SI>    return NULL;

SI>if(!pValuePoint)
SI>    pValuePoint = malloc(nBytes);
SI>else
SI>    if(nValueBytes != nBytes)
SI>        pValuePoint = realloc(pValuePoint, nBytes);

SI>if(!pValuePoint)
SI>    return NULL;

SI>nValueBytes = nBytes;
SI>memcpy(pValuePoint, pValue, nValueBytes); // проблема тут
SI>


Что же ты сделать-то хочешь?

На всякий случай, vDouble — лежит на стеке, а память под элементы массива выделяется в куче. А ты пытаешься скопировать всё это в один присест. Да еще не учитываешь, что размер double и void* может быть разным.
_____________________
С уважением,
Stanislav V. Zudin
Re[2]: memcpy
От: SmileIlya  
Дата: 15.04.15 14:37
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Что же ты сделать-то хочешь?


SVZ>На всякий случай, vDouble — лежит на стеке, а память под элементы массива выделяется в куче. А ты пытаешься скопировать всё это в один присест. Да еще не учитываешь, что размер double и void* может быть разным.


Хочу то я понятно чего, нормально скопировать pValuePoint значение.
Все это счастье часть общего алгоритма, я просто вынес все в одну ф-цию.
В реальности это выглядит сл. образом:

void fun(const void* pValue, size_t nBytes)
{
    size_t    nValueBytes = 0;
    void*    pValuePoint = NULL;
    
    if(!pValue || !nBytes)
        return NULL;
    
    if(!pValuePoint)
        pValuePoint = malloc(nBytes);
    else
        if(nValueBytes != nBytes)
            pValuePoint = realloc(pValuePoint, nBytes);
    
    if(!pValuePoint)
        return NULL;
    
    nValueBytes = nBytes;
    memcpy(pValuePoint, pValue, nValueBytes);
}

ну и понятно вызывается fun c параметрами (&vDouble,sizeof(vector<void*>) + (sizeof(void*) * (static_cast<vector<void*> const*>( pValue ))->size()))
Re[3]: memcpy
От: Stanislav V. Zudin Россия  
Дата: 15.04.15 14:44
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SVZ>>Что же ты сделать-то хочешь?


SVZ>>На всякий случай, vDouble — лежит на стеке, а память под элементы массива выделяется в куче. А ты пытаешься скопировать всё это в один присест. Да еще не учитываешь, что размер double и void* может быть разным.


SI>Хочу то я понятно чего, нормально скопировать pValuePoint значение.

SI>Все это счастье часть общего алгоритма, я просто вынес все в одну ф-цию.
хъ
SI>ну и понятно вызывается fun c параметрами (&vDouble,sizeof(vector<void*>) + (sizeof(void*) * (static_cast<vector<void*> const*>( pValue ))->size()))

Я правильно понимаю, что ты хочешь скопировать данные, лежащие в массиве?
Тогда указатель надо брать по-другому
pValuePoint = &vDouble[0];
А размер блока в байтах, соответственно, vDouble.size() * sizeof(double)

Только получается аццкая смесь из С и С++. Уверен, что твою задачу по-другому не решить?
_____________________
С уважением,
Stanislav V. Zudin
Re: memcpy
От: Igore Россия  
Дата: 15.04.15 14:53
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>Доброго всем дня.

SI>Есть проблема, кусок кода ниже.
SI>Суть проблемы в том, что при вызове memcpy приложение схлопывается, ругаясь на ошибку чтения.

SI>
SI>const void* pValue = (void*)vDouble.data();
SI>size_t nBytes = sizeof(double) * vDouble.size();
SI>size_t    nValueBytes = 0;
SI>void*    pValuePoint = NULL;

SI>if(vDouble.empty())
SI>    return NULL;

SI>if(!pValuePoint)
SI>    pValuePoint = malloc(nBytes);
SI>else //Это часть выкинуть таких условий не возникает
SI>    if(nValueBytes != nBytes)
SI>        pValuePoint = realloc(pValuePoint, nBytes);

SI>if(!pValuePoint)
SI>    return NULL;

SI>nValueBytes = nBytes;
SI>memcpy(pValuePoint, pValue, nValueBytes); // проблема тут
SI>

Попробуй с моими исправлениями, но я бы это все просто переписал и не мучился, ведь то что ты привел это.
auto pValuePoint = vDouble;
Отредактировано 15.04.2015 14:55 Igore . Предыдущая версия .
Re: memcpy
От: Mr.Delphist  
Дата: 15.04.15 14:58
Оценка:
if(nValueBytes != nBytes)
        pValuePoint = realloc(pValuePoint, nValueBytes);// вместо nBytes


Оно?
Re[4]: memcpy
От: SmileIlya  
Дата: 15.04.15 14:58
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Здравствуйте, SmileIlya, Вы писали:


SVZ>>>Что же ты сделать-то хочешь?


SVZ>>>На всякий случай, vDouble — лежит на стеке, а память под элементы массива выделяется в куче. А ты пытаешься скопировать всё это в один присест. Да еще не учитываешь, что размер double и void* может быть разным.


SI>>Хочу то я понятно чего, нормально скопировать pValuePoint значение.

SI>>Все это счастье часть общего алгоритма, я просто вынес все в одну ф-цию.
SVZ>хъ
SI>>ну и понятно вызывается fun c параметрами (&vDouble,sizeof(vector<void*>) + (sizeof(void*) * (static_cast<vector<void*> const*>( pValue ))->size()))

SVZ>Я правильно понимаю, что ты хочешь скопировать данные, лежащие в массиве?

SVZ>Тогда указатель надо брать по-другому
SVZ>pValuePoint = &vDouble[0];
SVZ>А размер блока в байтах, соответственно, vDouble.size() * sizeof(double)

SVZ>Только получается аццкая смесь из С и С++. Уверен, что твою задачу по-другому не решить?



Других вариантов нет. Это ф-ция одна из в чудо ядре. Писали давно и универсально
После всех этих развлечений, надо снова получить vector<double>
Re[5]: memcpy
От: _DAle_ Беларусь  
Дата: 15.04.15 15:12
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>Других вариантов нет. Это ф-ция одна из в чудо ядре. Писали давно и универсально

SI>После всех этих развлечений, надо снова получить vector<double>

Не нужно копировать сам вектор, нужно скопировать его содержимое, как это сделать уже показали выше. Потом просто конструируешь новый вектор из скопированных данных. А вообще какую-нибудь книжку по языку не помешало бы сначала почитать.
Re[2]: memcpy
От: SmileIlya  
Дата: 15.04.15 15:13
Оценка:
Здравствуйте, Igore, Вы писали:

I>Здравствуйте, SmileIlya, Вы писали:


SI>>Доброго всем дня.

SI>>Есть проблема, кусок кода ниже.
SI>>Суть проблемы в том, что при вызове memcpy приложение схлопывается, ругаясь на ошибку чтения.

SI>>
SI>>const void* pValue = (void*)vDouble.data();
SI>>size_t nBytes = sizeof(double) * vDouble.size();
SI>>size_t    nValueBytes = 0;
SI>>void*    pValuePoint = NULL;

SI>>if(vDouble.empty())
SI>>    return NULL;

SI>>if(!pValuePoint)
SI>>    pValuePoint = malloc(nBytes);
SI>>else //Это часть выкинуть таких условий не возникает
SI>>    if(nValueBytes != nBytes)
SI>>        pValuePoint = realloc(pValuePoint, nBytes);

SI>>if(!pValuePoint)
SI>>    return NULL;

SI>>nValueBytes = nBytes;
SI>>memcpy(pValuePoint, pValue, nValueBytes); // проблема тут
SI>>

I>Попробуй с моими исправлениями, но я бы это все просто переписал и не мучился, ведь то что ты привел это.
I>
I>auto pValuePoint = vDouble;
I>


Копирование проходит успешно, теперь другая проблема как из всего этого счастья получать опять полноценный вектор?
Re[5]: memcpy
От: Stanislav V. Zudin Россия  
Дата: 15.04.15 15:17
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SVZ>>Только получается аццкая смесь из С и С++. Уверен, что твою задачу по-другому не решить?


SI>Других вариантов нет. Это ф-ция одна из в чудо ядре. Писали давно и универсально

SI>После всех этих развлечений, надо снова получить vector<double>

А на принимающей стороне известно, что принятая пачка байтов это vector<double>? Размер массива известен или надо передать вместе с "полезной нагрузкой" или можно вычислить из размера блока памяти?

Что-то мне подсказывает, что стоит посмотреть, как работает сериализация.
И решить, достаточно ли передавать просто массив даблов или еще записывать количество элементов.

Т.е. либо
fun(&vDouble[0], sizeof(double) * vDouble.size());

Либо (псевдокод):

ByteOStream bs;                                         // Сериализовать массив
bs << vDouble.size();                                   // Записать размер массива
bs.write(&vDouble[0], sizeof(double) * vDouble.size()); // Записать данные

const void* pValue = bs.getBytes();                     // Блок байт
size_t sz = bs.size();                                  // размер блока в байтах

fun(pValue, sz);                                        // суперъядерное копирование

...
// И на принимающей стороне:
const void* pValue = ...                                // Принять блок памяти
size_t sz = ...
ByteIStream bs(pValue, sz);                             // Десериализовать
size_t num = 0;
bs >> num;
std::vector<double> another_vDouble(num);               // Выделить память
bs.read(&another_vDouble[0], num);                      // Загрузить полезные данные
_____________________
С уважением,
Stanislav V. Zudin
Re: memcpy
От: uzhas Ниоткуда  
Дата: 15.04.15 15:47
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>Суть проблемы в том, что при вызове memcpy приложение схлопывается, ругаясь на ошибку чтения.


kd112, перелогинься
Re[6]: memcpy
От: SmileIlya  
Дата: 15.04.15 16:42
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Здравствуйте, SmileIlya, Вы писали:


SVZ>>>Только получается аццкая смесь из С и С++. Уверен, что твою задачу по-другому не решить?


SI>>Других вариантов нет. Это ф-ция одна из в чудо ядре. Писали давно и универсально

SI>>После всех этих развлечений, надо снова получить vector<double>

SVZ>А на принимающей стороне известно, что принятая пачка байтов это vector<double>? Размер массива известен или надо передать вместе с "полезной нагрузкой" или можно вычислить из размера блока памяти?


SVZ>Что-то мне подсказывает, что стоит посмотреть, как работает сериализация.

SVZ>И решить, достаточно ли передавать просто массив даблов или еще записывать количество элементов.

SVZ>Т.е. либо

SVZ>
SVZ>fun(&vDouble[0], sizeof(double) * vDouble.size());
SVZ>

SVZ>Либо (псевдокод):

SVZ>
SVZ>ByteOStream bs;                                         // Сериализовать массив
SVZ>bs << vDouble.size();                                   // Записать размер массива
SVZ>bs.write(&vDouble[0], sizeof(double) * vDouble.size()); // Записать данные

SVZ>const void* pValue = bs.getBytes();                     // Блок байт
SVZ>size_t sz = bs.size();                                  // размер блока в байтах

SVZ>fun(pValue, sz);                                        // суперъядерное копирование

SVZ>...
SVZ>// И на принимающей стороне:
SVZ>const void* pValue = ...                                // Принять блок памяти
SVZ>size_t sz = ...
SVZ>ByteIStream bs(pValue, sz);                             // Десериализовать
SVZ>size_t num = 0;
SVZ>bs >> num;
SVZ>std::vector<double> another_vDouble(num);               // Выделить память
SVZ>bs.read(&another_vDouble[0], num);                      // Загрузить полезные данные
SVZ>


может я чего-то не понимаю, но как вернуть вектор после всех преобразований?
Re[3]: memcpy
От: Igore Россия  
Дата: 15.04.15 17:18
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>Копирование проходит успешно, теперь другая проблема как из всего этого счастья получать опять полноценный вектор?

Ну так точно также, 2 параметра поменять местами и все.
memcpy(pValuePoint, pValue, nValueBytes);//из вектора в массив
memcpy(vDouble.data(), pValuePoint, nValueBytes);//из массива в вектор
//ну или по С++
std::vector<double> result(pValuePoint, pValuePoint + nValueBytes);
Re: memcpy
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 15.04.15 17:49
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>Суть проблемы в том, что при вызове memcpy приложение схлопывается, ругаясь на ошибку чтения.

За чем ты так живёшь?
Sic luceat lux!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.