Я бы использовал что-то более высокого уровня, например, эластичные буферы. Смотрите это видео о сеансе кодирования в реальном времени, который реализует эти - реквизиты Per Vognsen для создания этого кода и для помещения в домен publi c (т. Е. Совершенно бесплатно для использования в любых целях, но я не юрист, поэтому принимайте все, что я говорю, с осторожностью:).
Вы хотите включить побитовый / ион / общий. c в исходный файл, а затем массив распределение становится простым. Эластичные буферы, возможно, наиболее близки к удобству C ++ std::vector
в C. Они предлагают API, который не похож на API C ++, транскрибированный в C - он находится на правильном уровне и позволяет очень просто использовать простые указатели (например, buf_len
указателя NULL равен нулю, не cra sh, buf_push(mybuf, element)
добавляет элемент в массив и расширяет его при необходимости и т. д. c.
#include <assert.h>
#include <string.h>
#include <stdlib.h>
// note that common.c includes nothing, so you have to set it up
#include "common.c"
#define buf_resize(b, n) ((n) <= buf_len(b) ? (b) : (((b) = buf__grow((b), (n), sizeof(*(b)), 0)), ((b) ? buf__hdr((b))->len = (n) : 0), (b)))
typedef struct {
int * pickup_Ind;
double *pickup_Val;
int * lInd;
double *lVal;
int * simul_Ind;
double *simul_Val;
} Data;
enum {
size1 = ...,
size2 = ...,
size3 = ...
}
Data make_Data(void) {
Data d;
memset(&d, 0, sizeof(d));
assert(buf_len(d->pickup_Ind) == 0);
buf_resize(d.pickup_Ind, size1);
buf_resize(d.pickup_Val, size1);
buf_resize(d.lInd, size2);
buf_resize(d.lVal, size2);
buf_resize(d.simul_Ind, size3);
buf_resize(d.simul_Val, size3);
}
int main(int argc, char **argv) {
Data d = make_Data();
assert(buf_len(d.pickup_Ind) == size1);
d.pickup_Ind[0] = 10;
assert(buf_len(d.pickup_Ind) == size1);
buf_push(d.pickup_Ind, 11);
assert(buf_len(d.pickup_Ind) == size1 + 1);
}
Если вы строите массивы, добавляя к ним элементы по одному в-первых, имеет смысл зарезервировать емкость для ожидаемого размера массива через buf_fit
(он резервирует только память, но буфер сохраняет свою длину (например, ноль)). Резервирование емкости совершенно необязательно, однако, это предотвращает перераспределение массивов при добавлении к ним элементов.
Таким образом:
Data make_Data(void) {
Data d;
memset(&d, 0, sizeof(d));
assert(buf_len(d->pickup_Ind) == 0);
buf_fit(d.pickup_Ind, size1);
buf_fit(d.pickup_Val, size1);
buf_fit(d.lInd, size2);
buf_fit(d.lVal, size2);
buf_fit(d.simul_Ind, size3);
buf_fit(d.simul_Val, size3);
}
int main(int argc, char **argv) {
Data d = make_Data();
assert(buf_len(d.pickup_Ind) == 0); // zero length: no data in the array (yet!)
assert(buf_cap(d.pickup_Ind) >= size1); // but it has the capacity we need
buf_push(d.pickup_Ind, 10);
buf_push(d.pickup_Ind, 11);
assert(buf_len(d.pickup_ind) == 2);
}
Если вы хотите использовать эластичные буферы в нескольких исходных файлах, вы ' Я буду работать против одного правила объявления (ODR). Таким образом, вам нужно будет выделить определения макросов и объявления функций из common.c
и в common.h
.
Если Data
только выделяется один раз, есть нет необходимости освобождать его перед выходом из программы: операционная система уже сделает это за вас. В противном случае вы можете добавить sh функцию для выполнения этой работы:
void free_Data(Data *d) {
buf_free(d.pickup_Ind);
buf_free(d.pickup_Val);
buf_free(d.lInd);
buf_free(d.lVal);
buf_free(d.simul_Ind);
buf_free(d.simul_Val);
assert(buf_len(d.pickup_Ind) == 0);
}