LINUX.ORG.RU

C и динамические массивы ...


0

0

Доброго времени суток,
сразу прошу извинить - не уверен, что заглавие темы корректно. Проблема следующего характера:

есть некий массив, точный размер которого не известен в начале работы программы; по мере обработки некого файла, я добавляю новые данные в этот массив, то есть он растет. Cушествуют ли механизмы в для работы с такого рода "массивами" по следующей схеме:

1) существует некий "массив" (object) в самом начале,
2) считываю элемент из внешнего файла, если элемент удолетворяет заданным условиям то:
увеличиваю размер "массива"(object) на 1 и добавляю этот элемент в него

1,2 до конца чтения файла.

Мне кажется, что это реализовывается посредством поинтеров ?

Буду благодарен за советы и если возможно кусок кода работаюшего по такому принципу

With best wishes,
Vic.



Thanks a lot !

psi
() автор топика

C или плюсы? Если плюсы - то там управление памятью в контейнерах 
более-менее автоматическое. Если Си - то аллоцируешь массив размером 
N, если он заполняется - делаешь realloc, скажем, в 1.5 раза больше 
(ну или в два, это смотря что тебе важнее - память или 
прозводительность - реаллок может довольно медленно происходить).


Т.е., типа

mystructs *t;
size_t cursize = INITIAL_SIZE;
size_t used = 0;

t = calloc(cursize, sizeof(mystruct));

while(!eof(file)) {
  t[used++] = read_struct(file);

  if (used > cursize) {  
    cursize *= 1.5;
    t = realloc(t, cursize * sizeof(mystruct));
  }
}

Только обработку ошибок добавить не забудь.

anonymous
()

таки перестаньте заниматься цереброфильством и юзайте таки связанные списки

Ex ★★
()

Только не делай realoc на каждый 1 байт/элемент и т.д., так как операции выделения памяти довольно дорогие. Увеличивай сразу на какой-то объем, например 4kb, 8kb ... Размер подобрать исходя из задачи (скорости поступления данных).

А если для этих данных не нужен произвольный доступ, а хватит и последовательного, то юзай списки.

kpanic ★★
()
Ответ на: комментарий от kpanic

> А если для этих данных не нужен произвольный доступ, а хватит и последовательного, то юзай списки.

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

iBliss
()
Ответ на: комментарий от iBliss

Доброго времени суток,
2iBliss

в файле данные [real(8)]. Каждому числу соответствует 4 индекса [integer(4)]. Мы считываем последовательно число за числом, знаем какие индексы у каждого числа. Затем формируем массив, в который в зависимости от условий добавляем те или иные считанные числа.
По условию задачи, нам понадобится из этого файла ~20-25% данных. Размер файла, который надо обработать - 20-25 Гб. Соответственно, размер массива, который будет создаваться "на лету" - 5-6 Гб

2All

Тут многие упоминают "списки". Не могли бы посоветовать литературу, где можно почитать про оные ?

Большое спасибо за советы, буду разбираться )

Best regards,
Vic.

psi
() автор топика
Ответ на: комментарий от psi

imho если данных настолько дофига списки и realoc-и умрут, лучше наверно ArrayList - список массивов + proxy, сбрасывающий часть из этих массивов на диск иначе ни какой памяти не хватит.

Наверно можно и без proxy, может swap и выдержит.

P.S. Список - это когда каждый элемент содержит узазатель на след. элемент.

struct list{ int value; struct list* next; }

YesSSS ★★★
()
Ответ на: комментарий от psi

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

YesSSS ★★★
()

использую связные списки, а если нужен поиск то лучше еще и деревья, к примеру для бинарного поиска red&black tree неплох, а если нужен бинарный поиск в кеше то лучше юзать splay tree.

alphex_kaanoken ★★★
()
Ответ на: комментарий от alphex_kaanoken

в смысле используй ;) это проще чем возится с указателем на указатель

alphex_kaanoken ★★★
()
Ответ на: комментарий от psi

> По условию задачи, нам понадобится из этого файла ~20-25% данных. Размер файла, который надо обработать - 20-25 Гб. Соответственно, размер массива, который будет создаваться "на лету" - 5-6 Гб

У вас 64-битная система, да? Иначе 5-6 гиг у вас в память не поместятся.

Кстати, еще можно делать mmap/mremap ручками (mremap непереносимый).

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.