Альтернатива мемсету

Я хочу инициализировать массив структур, однако второй параметр memset() принимает значение int. Есть ли другая функция, которая делает то же самое, но с (void *) имеет 2-й параметр? Я подумал о memcpy(), но он не устанавливает значение во всем массиве. Есть идеи?

структура:

typedef struct {
    int x;
    int y;
    char *data;
} my_stuff;

Код:

my_stuff my_array[];
my_array = malloc(MAX * sizeof(my_stuff));

my_stuff *tmp;
tmp->x = -1;
tmp->y = 1;
strcpy(tmp->data = "Initial state");

memset(my_array, tmp, sizeof(my_array));

person fabricemarcelin    schedule 19.04.2011    source источник
comment
Для чего именно вам нужен void*? memset в структуре с ненулевым параметром встречается довольно редко...   -  person user541686    schedule 19.04.2011
comment
ну, я просто ищу функцию, которая не принимает int в качестве второго параметра. Таким образом, я могу легко передать свою структуру в качестве параметра. Я знаю, что могу сделать это с помощью цикла for, но мне хотелось найти более интуитивно понятный способ инициализации массива.   -  person fabricemarcelin    schedule 19.04.2011
comment
А, понятно... к сожалению, в C нет ничего, что могло бы сделать это за вас. :(   -  person user541686    schedule 19.04.2011


Ответы (3)


memset() устанавливает значение каждого байта. Нет проблем с приведением указателя к целому числу (второй параметр). Основная проблема в том, что он будет больше байта.

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

Также обратите внимание, что с вашим кодом возникнут дополнительные проблемы, если он заработает. Во-первых, sizeof(my_array) возвращает общее количество байтов в структуре данных, а не количество элементов. Кроме того, ваш код просто скопировал бы указатель. Вам нужно фактически скопировать данные, на которые он указывает, поскольку целью являются не указатели, а фактические структуры.

person Jonathan Wood    schedule 19.04.2011
comment
Есть wmemset, но размер блока wchar_t, что по-дурацки 16-битное в Windows и 32-битное везде... - person R.. GitHub STOP HELPING ICE; 19.04.2011
comment
@R..: Да, я забыл про wmemset(). Но, да, он был предназначен больше для символов, чем для целых чисел. Даже в 32-битных системах он не сможет копировать указатели в 64-битных системах. - person Jonathan Wood; 19.04.2011

Для этого нет стандартной функции — вам просто нужно вызвать memcpy() в цикле:

my_stuff *my_array = malloc(MAX * sizeof(my_stuff));
my_stuff tmp;
size_t i;

tmp.x = -1;
tmp.y = 1;
tmp.data = "Initial state";

for (i = 0; i < MAX; i++)
    memcpy(&my_array[i], &tmp, sizeof tmp);

Обратите внимание, что вы не можете strcpy() превратить в tmp.data, потому что это просто висячий указатель без выделенной памяти.

person caf    schedule 19.04.2011
comment
+1 Однако я предпочитаю объявлять tmp константой: const my_stuff tmp = { -1, 1, "Initial state" }; - person Ben; 19.04.2011
comment
@Ben: Да, и даже лучше с назначенными инициализаторами C99 (и вы также должны сделать это static). - person caf; 19.04.2011

Вы не можете использовать memset() в этом случае. Вы должны использовать memcpy(). Просто попробуйте это: 1. malloc ваш массив 2. инициализируйте первый элемент массива 3. скопируйте первый элемент во все элементы

/* step 1 */
my_stuff *my_array = malloc(MAX * sizeof(my_stuff));
int i;

/* step 2 */
my_array[0].x = -1;
my_array[0].y = 1;
my_array[0].data = "Initial state";

/* step 3 */
for (i = 1; i < MAX; i++)
    memcpy(&my_array[i], &my_array[0], sizeof(my_array[0]));
person BiGYaN    schedule 19.04.2011