The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Как выделить память под структуру"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Как выделить память под структуру"
Сообщение от Alexander emailИскать по авторуВ закладки on 11-Мрт-03, 21:34  (MSK)
Не подскажете ли, как правильно выделить память под структуру типа
typedef struct{float charge;
               char atom_type[MAX_ATOM_TYPE_LEN+1];} t_one_atom;
typedef struct {int size;
                t_one_atom* atom;} t_one_residue;
typedef struct {int size;
                t_one_residue* residue;} t_protein_data;
В разных residue содержатся разное количество atom, да самих residue не известно сколько до завершения работы программы. Спасибо.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "RE: Как выделить память под структуру"
Сообщение от XMan Искать по авторуВ закладки on 11-Мрт-03, 23:35  (MSK)
Вообще-то у тебя известны размеры всех структур - там же указатели :)

Можешь пойти 2-мя путями:

1. Стандартное выделение под структуру t_protein_data и для каждого residue и atom опять дергается выделение памяти.

2. Подсчет количества элементов residue (N) и atom (M) и выделение памяти под размер sizeof(t_protein_data)+N*sizeof(t_one_residue)+M*sizeof(t_one_atom). После чего размещаешь свои residue и atom внутри выделенной памяти.

Путь 2 используется в функциях получения информации о пользователе, например, getpwnam или getgrgid.

PS. Кстати, пока я вижу только структуру типа:

t_protein_data Г
                     |  int
                     |  t_one_residue -> Г
                     L                          |  int
                                                 |  t_one_atom -> Г
                                                 L                      |  float
                                                                         |  char [количество]
                                                                         L

То есть у тебя всегда в t_protein_data ссылка на одну структуру t_one_residue, в которой присутствует ссылка на одну структуру t_one_atom. В связи с чем вопрос - если максимальное количество atom_type больше 0, то можно согласиться, что реально их может быть разное количество, но что значит "самих residue не известно сколько" когда у тебя всего одна ссылка на эту структуру, то есть и структура получается всего одна ?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "RE: Как выделить память под структуру"
Сообщение от Alexander emailИскать по авторуВ закладки on 12-Мрт-03, 13:03  (MSK)
Возможно я ошибся определяя структуру. Выглядеть должно примерно так: структура t_proetein_data содержит набор структур residue и их количество в int size. Количество residue заранее не известно, было бы не плохо перевыделять память чем-то типа realloc. С другой стороны residue содержит неопределенное количество структур atom. Ситуации бывает две - надо создать новую residue (редко) или новую atom внутри текущей residue (часто). В учебнике я, к сожалению, не нашел информации о таком случае, поэтому буду признателен за любую помощь.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "RE: Как выделить память под структуру"
Сообщение от XMan Искать по авторуВ закладки on 12-Мрт-03, 15:56  (MSK)
Угу. Ну это не в книге по языку, а в книге по программированию могло и должно было быть. В частности - динамические массивы. В еще большей частности - очереди, стеки, двунаправленные списки и т.п.

Как вариант, структуры меняются на следующее:

typedef struct {
float charge;
char atom_type[MAX_ATOM_TYPE_LEN+1];
} t_one_atom;

typedef struct {
t_one_atom atom;
t_one_residue *next;
} t_one_residue;

typedef struct {
t_one_residue* residue;
} t_protein_data;

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

t_protein_data Г
                     |  t_one_residue -> Г
                     L                          |  t_one_atom
                                                 |  t_one_residue -> t_one_residue -> ... -> NULL
                                                 L

Количество элементов можно посчитать пройдя от первого до NULL:

t_one_residue *current=protein->residue;
int n=0;
while (current) {
n++;
current=current->next;
};

Таким образом можно попасть к любому элементу списка. Для добавления элемента делается следующее:

t_one_residue *new=(t_one_residue *)malloc(sizeof(t_one_residue));
new->next=NULL;
// заполнение новой структуры
...
// структура заполнена, добавляем ее к списку
t_one_residue *current=protein->residue;
if (current) {
while (current->next) current=current->next;
current->next=new;
} else {
// первый элемент
protein->residue=new;
};

Желательно так же добавить ссылку назад (... *next,*prev), которая будет ссылаться на предыдущий элемент. Проще при навигации будет. Например, при освобождении памяти одного элемента тебе нужно будет сделать следующее:

// считаем, что current - элемент, который нужно удалить

if (current->prev) current->prev->next=current->next;
else
// первый элемент
protein->residue=current->next;

// освобождаем память, занятую содержимым структуры.
// в данном случае структура t_one_atom не является динамической
// и можно просто освободить память, занятую самой структурой current

free(current);

Короче, что-то в этом духе :)

PS. Я незнаю что ты пишешь, но если структуры такими и останутся, то проще сделать вот так:

typedef struct {
float charge;
char atom_type[MAX_ATOM_TYPE_LEN+1];
t_one_atom *next, *prev;
} t_one_atom;

typedef struct {
t_one_atom* residue;
} t_protein_data;

При этом у тебя выбрасывается по большому счету лишняя структура :)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "RE: Как выделить память под структуру"
Сообщение от Alexander emailИскать по авторуВ закладки on 12-Мрт-03, 17:11  (MSK)
Большое спасибо, XMan.
Попробую сделать, как ты предложил.

P.S. Прости за глупые вопросы, но я биолог и достаточно далек от програмирования. Удач.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "RE: Как выделить память под структуру"
Сообщение от Alexander emailИскать по авторуВ закладки on 12-Мрт-03, 17:35  (MSK)
Прости XMan, я не понял, как добратся к информации в receptor_data->residue[n].atom[m].charge в предложеной тобой структуре?
  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "RE: Как выделить память под структуру"
Сообщение от XMan Искать по авторуВ закладки on 12-Мрт-03, 18:39  (MSK)
Вот это, пожалуй, самое неудобное. Для доступа к произвольной структуре тебе нужно пройти по цепочке от известной структуры к искомой. Примеры:

1. Известной структуры нет. Тогда идем от начала:

int i=0;
t_one_residue *current=receptor_data->residue;
while (i<n) {
if (! current) break; // если элементов в списке меньше, чем n, то выходим из цикла
i++;
current=current->next;
};
if (current) {
// нашли структуру. что-то делаем
...
};

2. Известен current и его положение i в списке. Ищем структуру с индексом n:

while (i<>n) {
if (i > n) {
// идем назад
current=current->prev;
i--;
} else {
// идем вперед
current=current->next;
i++;
};
if (! current) break;
};
if (current) {
// нашли структуру. что-то делаем
...
};

Во всех примерах обращение к atom[m] будет выглядеть, как "current->atom[m]".

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "RE: Как выделить память под структуру"
Сообщение от Alexander emailИскать по авторуВ закладки on 12-Мрт-03, 19:23  (MSK)
Все понятно, но вот строка
typedef struct {
        t_one_atom *atom;
        t_one_residue *next,*prev;   <------!!!!!! error
        } t_one_residue;
напрочь отказывается компилится gcc-2.96    :(((
  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "RE: Как выделить память под структуру"
Сообщение от XMan Искать по авторуВ закладки on 12-Мрт-03, 20:53  (MSK)
Согласен, должна быть такая запись:

typedef struct {
        struct t_one_atom *atom;
        struct t_one_residue *next,*prev;
} t_one_residue;

или вот такая:

struct t_one_residue {
        struct t_one_atom *atom;
        struct t_one_residue *next,*prev;
};

Это уж как тебе больше нравится :)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "RE: Как выделить память под структуру"
Сообщение от Alexander emailИскать по авторуВ закладки on 12-Мрт-03, 22:20  (MSK)
Спасибо XMan,
Я упешно запустил тестовую задачу - все работает!!!
С меня гора виртуального пива ;))).

P.S. Хотя если ты из Киева то можно и не совсем виртульного ;))). Спасибо.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "RE: Как выделить память под структуру"
Сообщение от XMan Искать по авторуВ закладки on 12-Мрт-03, 23:38  (MSK)
Ну если ты там знаешь Лясковского Андрея, то можешь ему отдать. Скажешь от меня. Если не вспомнит по нику, напомни ему про Quake в ДонГТУ и кто там был в перво десятке по универу :)
  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру