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: 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[4]: memcpy
От: _DAle_ Беларусь  
Дата: 15.04.15 14:51
Оценка: :)
Здравствуйте, Stanislav V. Zudin, Вы писали:

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


Да нет, ты не понял, он хочет "нормально скопировать pValuePoint значение"
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[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[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!
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];

дальше не смотрел, но судя по коментам там тоже не все гладко
Как много веселых ребят, и все делают велосипед...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.