Общее программирование на С Вопросе - PullRequest
2 голосов
/ 31 марта 2011

Я пишу динамический массив в C.

typedef struct __c_array {
    void**_elem;
    int  cur_size;
    int  capacity;
}c_array;

Мой интерфейс выглядит следующим образом:

extern void push_back_c_array ( c_array*, void *);

Теперь пользователь должен будет выделить память для элемента, который будет помещен в массив. Есть ли способ избежать этого, используя void *.

Я хочу использовать это, чтобы сделать следующее

int a = 5;
push_back_c_array ( <ARRAY_PTR>, a );

Возможно ли это.

Ответы [ 4 ]

2 голосов
/ 31 марта 2011

Это возможно, если вы предоставите версию push_back_c_array (), которая будет копировать предоставленное значение.Для этого вам понадобится дополнительный аргумент, который определяет размер значения:

push_back_c_array(c_array* arr, void* val, unsigned int size);

Вы выделяете память в куче для нового значения, а затем выполняете memcpy.Но после этого вам придется вернуть его обратно.Итак, вам нужно запомнить, какие значения выделены вами, а какие - вызывающим.Скорее противно ... Итак, если вы делаете это - делайте это всегда, и опишите это соглашение в документации к вашей функции.

0 голосов
/ 31 марта 2011

ваш пример с a = 5 должен работать до тех пор, пока вы будете использовать целые числа или любой другой тип, имеющий такой же размер, как int.Пользователь универсального массива захочет выдвинуть структуры, как и ваш.Но большие элементы не могут / не должны передаваться по значению, но должен передаваться его указатель.

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

0 голосов
/ 31 марта 2011

Возможно, вам лучше будет выделить небольшой кусок памяти (возможно, для хранения союзов) в начале и отодвигать элементы назад, пока вы не заполните их. Затем либо realloc, либо выделите массив в два раза больше и скопируйте все.

0 голосов
/ 31 марта 2011

Ваш примерный массив содержит элементы типа (void *).Он держит указатели.Вы, кажется, хотите, чтобы он содержал произвольные типы.В этом случае и инт.Вы хотите хранить копии вставленных данных или просто хранить указатели, данные вам вызывающим абонентом?

Некоторое время назад я хотел простой массив типа поведения для игры, которую я писал, и придумал xrlist.Некоторое время спустя я захотел сохранить их и получить к ним произвольный доступ, поэтому придумал xrhash .

xrlist и предоставленные пользователем указатели xrhash store и ожидали, что все элементы будут одного типа (xrhash имеетхэш-код и функция обратного вызова сравнения)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...