2015-01-31 2 views
0

Я работаю над проектом, который использует динамический массив структур. Чтобы избежать хранения количества структур в его собственных переменных (количество структур), я использовал массив указателей на структурные переменные с терминатором NULL.Сохранение динамического массива структур

Например, предположим, что мой тип структуры определяется как:

typedef struct structure_item{ 
    /* ... Structure Variables Here ... */ 
} item_t; 

Теперь, скажем, мой код имеет item_t **allItems = { item_1, item_2, item_3, ..., item_n, NULL }; и все item_# s имеют тип item_t *.

Используя эту настройку, мне тогда не нужно отслеживать другую переменную, которая сообщает мне общее количество элементов. Вместо этого, можно определить общее количество предметов, по мере необходимости, говоря:

int numberOfStructures; 
for(numberOfStructures = 0; 
    *(allItems + numberOfStructures) != NULL; 
    numberOfStructures++ 
); 

При выполнении этого кода, он подсчитывает общее количество указателей перед тем NULL.

Для сравнения, эта система похожа на строки в стиле C; тогда как отслеживание общего количества структур будет похоже на строку в стиле Паскаля. (Потому что C использует завершенный массив символов NULL против Pascal, который отслеживает длину его массива символов.)

Мой вопрос довольно прост: массив указателей (указатель на указатель на структуру) действительно необходим или может это нужно сделать с помощью массива structs (указатель на struct)? Может ли кто-нибудь предоставить лучшие способы справиться с этим?

Примечание: важно, что решение совместимо с обоими C и C++. Это используется в библиотеке обертки, которая обертывает библиотеку C++ для использования в стандартном C.

Спасибо всем заранее!

+1

Если у вас нет простого способа определить последнюю структуру типа NULL, вы можете использовать косвенные ссылки с помощью указателей. Более того, с помощью указателей вы можете реорганизовать, не перемещая большие структуры, и расширяться без больших перераспределений. Однако, как гладкое, как конечное решение NULL, перемещение всего массива для определения длины может стать дорогостоящей операцией, в которой может быть уменьшена переменная длины или конечный указатель. –

+0

Простой вопрос: если один из указателей, которые вы храните, оказался установленным в NULL, что произойдет со всем, что хранится после этого указателя? Скорее всего, вы потеряете следы указателей и заостренной памяти, вызывая утечку памяти. Поэтому, я думаю, вам нужно было убедиться, что этого никогда не произойдет. – SirDarius

+0

@SirDarius, об этом я и думал, и я надеюсь, что кто-то может предложить решение, которое будет обрабатывать этот случай. Тем не менее, сохранение количества структур представляет такой же риск, потому что «int numberOfStructures» может быть так же легко потерян. – SpencerD

ответ

2

Что вам нужно, это контрольное значение, узнаваемое действительное значение, которое означает «ничего». Для указателей стандартное значение дозорного устройства составляет NULL.

Если вы хотите использовать свои структуры напрямую, вам нужно будет принять решение о контрольном значении типа item_t и проверить это. Ваш звонок.

+0

Вот чего я боялся. Я полагаю, что я буду придерживаться массива указателей, потому что мой код уже написан таким образом, и мои фактические структуры имеют некоторые накладные расходы. Спасибо за ввод. – SpencerD

1

Да, у вас может быть массив структур и (по крайней мере) один из этих определенных дозорных элементов (это то, что «\ 0» используется в конце строк, и указатель NULL в вашем случае).

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

Например, предположим, что у нас есть тип структуры

struct X {int a; char *p}; 

затем определить функцию

int is_sentinel(struct X x) 
{ 
    return x.p == NULL; 
} 

Это будет означать любой структуры X, для которых элемент р может быть использован в качестве NULL дозорный (и член a в данном случае не имеет значения).

Затем просто петля ищет часового.

Примечание: для совместимости как с C, так и с C++ тип структуры должен быть совместимым (например, POD).