Как использовать функцию Memcpy()

В конце я хочу использовать memcpy вместо

block_orig_left[i1][j1]=block_orig[i1][j1];
pred_orig_left [i1][j1]=block_pred[i1][j1];

У меня ошибка при использовании memcpy

src/coder.c:909: ошибка: недопустимые операнды для двоичного * (имеют 'unsigned int' и 'int **')
src/coder.c:910: ошибка: недопустимые операнды для двоичного * (имеют 'unsigned интервал» и «инт **»)

int **block_orig_left=NULL;

block_orig_left=intmatrix(BSIZE_Y_LEVEL[levelv], BSIZE_X_LEVEL[levelv]);
pred_orig_left=intmatrix(BSIZE_Y_LEVEL[levelv], BSIZE_X_LEVEL[levelv]);

for(i1=0; i1<BSIZE_Y_LEVEL[levelv]; i1++)
for(j1=0; j1<BSIZE_X_LEVEL[levelv]; j1++)
{
    block_orig_left[i1][j1]=block_orig[i1][j1];
    pred_orig_left[i1][j1]=block_pred[i1][j1];
    Average_block_orig_left+=block_orig[i1][j1];        
} 
memcpy(block_orig_left, block_orig, sizeof(int **)*block_orig);

memcpy(pred_orig_left, block_pred,  sizeof(int **)*block_pred);

Как правильно использовать memcpy?


person bruno    schedule 20.12.2010    source источник
comment
Вы умножаете указатель на беззнаковое целое число. Вы не можете этого сделать (и не хотите).   -  person Roddy    schedule 21.12.2010


Ответы (3)


Вы умножаете размер int** на int**, что не имеет смысла. Другими словами, если вы хотите узнать вес всех автомобилей на грузовике, вы не можете умножить «вес 1 автомобиля» на «грузовик». Вы должны умножить вес 1 автомобиля на количество автомобилей в грузовике.

Третий параметр memcpy — это количество байтов, которые вы хотите скопировать. Вы правильно получаете размер int*, но затем хотите умножить его на количество int* в структуре. Итак, если я правильно понимаю ваш код, вы хотели бы использовать

sizeof(int**) * BSIZE_Y_LEVEL[levelv] * BSIZE_X_LEVEL[levelv]

поскольку структуры, которые вы копируете, содержат такое количество двойных указателей int.

РЕДАКТИРОВАТЬ: Глядя на ответ Дэвида Яу, я понимаю, что он прав. Мне не удалось учесть тот факт, что внутренние указатели, скорее всего, не все были выделены сразу, а скорее в цикле for или что-то в этом роде, поэтому их нужно было копировать аналогичным образом. Мой способ выше скопировал бы правильный объем памяти, но это не обязательно была бы правильная память.

person Derek    schedule 20.12.2010
comment
Спасибо, ребята, это правильный способ сделать это. Я уже сделал это, просто разместил неправильный код. Я больше не выдает ошибку, но программа не работает должным образом. Спасибо, в любом случае - person bruno; 21.12.2010
comment
Как я уже упоминал в своем редактировании, посмотрите ответ Дэвида Яу. У него был лучший ответ, чем у меня, потому что я забыл, что вы, вероятно, выделили каждый из подмассивов по отдельности, в цикле for или что-то в этом роде. Это означает, что они, вероятно, не являются смежными, и каждый из них должен запоминаться отдельно. И вы должны использовать sizeof (int), а не sizeof (int **), так как вы считаете целые числа, а int ** - это то, что указывает на них. Хотя в большинстве случаев так и будет. - person Derek; 21.12.2010

Я предполагаю, что block_orig, block_pred, block_orig_left и pred_orig_left объявлены как int**. Только один из них показан в вашем коде.

Ошибка, которую вы получаете, находится в параметре memcpy, sizeof(int **)*block_orig. Вы пытаетесь умножить целое число (sizeof(int**)) на переменную типа int**. Компилятор не может понять это умножение.

Вам нужно исправить параметр длины на memcpy, но это все равно не будет работать должным образом.

// Still won't work.
memcpy(block_orig_left, block_orig, sizeof(int) * BSIZE_Y_LEVEL[levelv] * BSIZE_X_LEVEL[levelv]);

int** — это массив указателей на массивы целых чисел. Если вы попытаетесь memcpy int**, вы в конечном итоге перезапишете внешний массив. Поэтому я думаю, что вам нужен цикл и копирование внутренних массивов.

Это должно работать.

for(int i = 0; i < BSIZE_Y_LEVEL[levelv]; i++)
{
    memcpy(block_orig_left[i], block_orig[i], sizeof(int) * BSIZE_X_LEVEL[levelv]);
}
person David Yaw    schedule 20.12.2010
comment
Умножение на sizeof(int) не обязательно будет правильным, поскольку int не обязательно должен быть того же размера, что и указатель. Я верю. :) Думаю, он правильно использовал sizeof(int**). - person Derek; 21.12.2010
comment
Он пытается скопировать данные, а не указатели на хранилище. Я думаю, что sizeof(int) правильный, но int** означает, что один memcpy этого не сделает. См. редактирование. - person David Yaw; 21.12.2010
comment
Ах, правда. Я неправильно понял его структуру данных. - person Derek; 21.12.2010

memcpy(block_orig_left, block_orig, sizeof(int **)*block_orig);

sizeof(int **)*block_orig - это умножение размера на указатель. Я думаю, вы знаете, что умножение указателя не имеет смысла и невозможно, как вы можете видеть из ошибки компилятора.

Я не знаю, что означают block_orig или ваши другие (кстати, вы слышали о самоописываемых именах переменных?) переменные, но memcpy принимает в качестве аргументов цель, источник и размер в байтах.

В вашем случае с целочисленной матрицей что-то вроде sizeof(int) * numberOfElementsToCopy имело бы смысл, если целевая память непрерывна (т.е. 2D-массив).

person AndiDog    schedule 20.12.2010