Пустой массив, переменные динамического размера в C

Хорошо, поэтому я постараюсь объяснить мою проблему ясно.

Я хотел бы иметь функцию, которая будет сортировать массив чего угодно, основываясь на размере элемента, смещении и размере переменной в элементе (для использования со структурами).

Итак, моя функция будет выглядеть так:

void sort(void* array, size_t elem_size, int elem_count, size_t operand_offset, size_t operand_size)

массив - это указатель на начало массива

elem_size — размер одного элемента в массиве

elem_count — количество элементов в массиве

operand_offset — это смещение переменной в элементе, на котором основывается сортировка (было бы 0, если элемент представляет собой только одну переменную, но может быть больше, если элемент является структурой)

размер_операнда - это размер этой переменной

В этой функции мне нужно создать временную переменную, я бы сделал это так:

void* temp = malloc(elem_size);
*temp = *(array+ i*elem_size);

но компилятор не соглашается: разыменовывает указатель void*, и он не знает размер моей временной переменной...

Я знаю, что могу сделать это байт за байтом, но я хотел бы знать, есть ли лучший способ.

Итак, мой вопрос: как установить «размер» указателя на elem_size?

Дополнительный вопрос: могу ли я ввести array[i] для доступа к элементу, если известен размер?


EDIT Итак, моя проблема решена, я должен использовать memcpy

Но теперь у меня другая проблема, которую я не ожидал.

Учитывая размер и смещение операнда внутри элемента, как я могу извлечь его и сравнить?

вроде как:

void *a = malloc(operand_size);
void *b = malloc(operand_size);
memcpy(a, array+i*elem_size + operand_offset, operand_size);
memcpy(b, array+j*elem_size + operand_offset, operand_size);

if (a < b)
...
else
...

Как я могу это сделать?


*РЕДАКТИРОВАТЬ 2: * Ну, наконец, было слишком сложно управлять оператором if для каждого размера операнда, поэтому я сделал что-то совершенно другое.

Итак, в основном у меня было void *array, содержащее n элементов, и я писал функцию для его сортировки.

Но вместо того, чтобы напрямую указывать смещение и размер операнда внутри элемента, я дал функции другую функцию для сравнения двух элементов. Это хорошо работает

int compareChar(void* a, void* b);
int compareShort(void* a, void* b);
int compareInt(void* a, void* b);
int compareLong(void* a, void* b);
int compareFOO(void* a, void* b);

void sort(void* array, size_t elem_size, int elem_count, int (*compare)(void*,void*));

person user2073752    schedule 14.02.2013    source источник
comment
Как вы будете сравнивать данные, которые вы извлекаете из этого места?   -  person cnicutar    schedule 15.02.2013
comment
Вы собираетесь сравнивать значения произвольного размера, заданные operand_size, верно? В любом случае, каков тип этих значений? Струны? Целые числа произвольного размера? Маленький/большой порядок байтов?   -  person Code Painters    schedule 15.02.2013
comment
Да, операнды будут int, но, возможно, в будущем это могут быть char или long..   -  person user2073752    schedule 15.02.2013
comment
Вы говорите, что *array — это указатель на начало массива; ты не имеешь в виду, что array это указатель на начало массива?   -  person Keith Thompson    schedule 15.02.2013
comment
Да это я и имею в виду :)   -  person user2073752    schedule 15.02.2013


Ответы (1)


Не могли бы вы просто использовать memcpy? Это, вероятно, сделает это наиболее эффективным образом.

uint8_t* temp = malloc(elem_size);
memcpy(temp, array + i * elem_size, elem_size);
person Bill Lynch    schedule 14.02.2013
comment
Что ж, спасибо тебе! Это именно то, что я искал. Это было слишком очевидно, поэтому я не подумал об этом ^^ - person user2073752; 15.02.2013
comment
Непереносимо выполнять арифметику указателя на void *. На самом деле он работает только на нескольких компиляторах. Приведите к char * перед выполнением арифметических действий, если вас вообще беспокоит переносимость. - person Dietrich Epp; 15.02.2013