Здравствуйте, vis1979, Вы писали:
АТ>>Это, похоже, именно С...
V>Да, это С, компиляция производиться на Borland C++ 3.1
АТ>>Если это именно C, то
АТ>>АТ>>...
АТ>> struct TimerStruct* tempTimerEl = malloc(sizeof *tempTimerEl);
АТ>>...
АТ>>
АТ>>Т.е. во-первых, никакого приведения типа не надо, и, во-вторых, 'sizeof' лучше натравить на указатель-получатель, а не на тип.
V>Понятно, спасибо, это я учту, но вот что сказано в helpe на malloc
V>V> char *str;
V> /* allocate memory for string */
V> if ((str = (char *) malloc(10)) == NULL)
V> {
V> printf("Not enough memory to allocate buffer\n");
V> exit(1); /* terminate program if out of memory */
V> }
V>
В стародавние времена в языке С не было указателей на 'void' и функция 'malloc' возвращала 'char*'. По этой причине в те времена было принято всегда применять приведение типа к результату 'malloc' (даже если нужен был именно 'char*'). Вот этот пример их help-а как раз и демонстирурует эту давно устаревшую манеру. Старинный пример забыли подправить. Или было просто лень.
Сейчас наоборот выполнять такое приведение типа весьма и весьма не рекомендуется. По причинам, описанным в моем соседнем сообщении.
V>то есть приведение типа явно указано, как я понимаю ошибки в моем описании нет,
V>и вы представили лишь улучшение или я не до конца что то понимаю?
Ошибки нет, есть избыточность. И потенциальная опасность.
АТ>>Не понятно почему тип возврата — 'void*', а не 'struct TimerStruct*'.
V>
Да собственно и не знаю почему просто tempTimerEl это элемент списка, для которого
V>выделяется память и заполняются поля, далее возращается в качестве результата функции
V>чтобы потом по идентификатору tempTimerEl его можно было найти в списке и удалить
V>вот такой функцией unsigned char DeleteTimer(void * ID_Timer)
опять же с типом void *
По прежнему не понятно, почему не сделана типизация...
V>то есть по сути TimerKLZ[i] используется в следующем виде DeleteTimer(TimerKLZ[i]);
V>на самом деле в качестве void* подразумевался просто возвращаемый адрес элемента
V>в принципе все работает и вроде стабильно, но посто закрались смутные сомнения
V>правильно ли я выделяю память для списка указателей на void в таком виде:
V>V>void ** TimerKLZ;
V> if ((TimerKLZ= (void **) malloc(sizeof(void *)*CountKLZ))==NULL)
V> {
V> return 0;
V> }
V>
Формально правильно, но опять же — в такой записи содержатся ненужные инварианты и избыточные приведения. Если завтра ты решишь перейти с типа 'void*' на какой-нибудь другой, тебе придется сделать исправления в трех местах: объявление 'TimerKLZ', приведение типа и "параметр" 'sizeof'. В моем варианте исправление пришлось бы делать только в первом месте а строчку с 'malloc' вообще исправлять бы не надо было.
АТ>>По-прежнему не понятно, почему массив именно 'void*'-ов...
V>вопрос а как мне объявить массив указателей на TimerStruct?
V>таким же образом? "struct TimerStruct ** TimerKLZ;" — ???
Да.
V>и потом выделение
V>V> if ((TimerKLZ= (struct TimerStruct **) malloc(sizeof(struct TimerStruct *)*CountKLZ))==NULL)
V> {
V> return 0;
V> }
V>
...
if ((TimerKLZ = malloc(CountKLZ * sizeof *TimerKLZ)) == NULL)
...