- проблемы с памятью ;), DeadMustdie, 11:02 , 09-Фев-05 (1)
>Я программирую под Linux (2.4.22) на си, используя компилятор gcc 3.4.3 >Посоветуйте самый безглючный способ инициализации памяти: > 1) объявить static char *buffer; затем в main(): buffer = (char >*) calloc(SIZE, 1); а в подключаемых файлах писать extern char *buffer; Не должно даже линковаться. Переменные класса static не видны за пределами модуля трансляции (в простейшем случае - c-файла), в котором они объявлены. > > 2) объявить в каждом из файлов свой static char *buffer; в >каждой функции >писать buffer = (char *) calloc(SIZE, 1); а затем free(buffer); > А если упомянутые функции друг друга вызывают, то можно утечки памяти заработать. Лучше по мере надобности память в оных функциях выделять, а по окончании оной надобности - освобождать. > Просто блин эти сегфолты действуют на нервы... > Они не сами по себе возникают. Вообще SIGSEGV - вещь крайне полезная. Позволяет быстро найти идиотские ошибки. >И ещё вопрос: может ли возникать сегфолт при работе с памятью если >ядро старое? (может быть, вопрос глупейший) Если версия GLIBC с ядром не дружит (например, GLIBC сильно старая, а ядро сильно новое), возможны кое-какие проблемы. Редко, но бывает. В основном при использовании функций трассировки другого процесса, установке ловушек (trap) и работе с pthread'ами.
- проблемы с памятью ;), maverick, 20:47 , 09-Фев-05 (2)
>Не должно даже линковаться. Переменные класса static не видны за >пределами модуля трансляции (в простейшем случае - c-файла), в >котором они объявлены. >То есть как это не видны? Видны. Иначе зачем вообще такая фича как extern ? >> >> 2) объявить в каждом из файлов свой static char *buffer; в >>каждой функции >>писать buffer = (char *) calloc(SIZE, 1); а затем free(buffer); > >Лучше по мере надобности память в оных функциях выделять, а по >окончании оной надобности - освобождать. > Допустим мне надо создать в программе три часто исплользуемых буфера. Дак что же, мне придётся тогда в каждой подпрограмме их объявлять, аллокейтить, юзать, а потом освобождать? Как-то гиморно.. Неужели нельзя сделать всё первым способом?
- проблемы с памятью ;), Xenu, 22:01 , 09-Фев-05 (3)
> >>Не должно даже линковаться. Переменные класса static не видны за >>пределами модуля трансляции (в простейшем случае - c-файла), в >>котором они объявлены. >> > >То есть как это не видны? Видны. Иначе зачем вообще такая фича >как >extern ? Как это возможно, что static переменная объявленная в одном файле видно из другого файла. Не покажите ли что линкер напечатал при собирании такого кода.extern служит не для того что бы static переменные в другом файле использовать. >>> >>> 2) объявить в каждом из файлов свой static char *buffer; в >>>каждой функции >>>писать buffer = (char *) calloc(SIZE, 1); а затем free(buffer); >> >>Лучше по мере надобности память в оных функциях выделять, а по >>окончании оной надобности - освобождать. >> > >Допустим мне надо создать в программе три часто исплользуемых буфера. >Дак что же, мне придётся тогда в каждой подпрограмме их объявлять, аллокейтить, >юзать, а потом освобождать? Как-то гиморно.. Неужели нельзя сделать всё первым >способом? объявите 3 буфера или один. но только обращайтесь к ним через функции доступа и не пишите напрямую в буфера из других мест.
- проблемы с памятью ;), dimus, 12:36 , 10-Фев-05 (4)
Я пришел к выводу, что оптимальным вариантом во многих случаях является использование подхода, подобного классам в С++. Напишите семейство функций, внутри которых идет работа с этим буфером, как с ЗАКРЫТЫМ объектом. Пусть ничто из внешнего мира не обращается к нему иначе, чем через них. Тогда если ошибки и возникнут, их можно будет очень легко отследить и ликвидировать.typedef struct _tagBUF { void* buf; int buf_size; // И т.д. } BUF; // "Конструктор" int buf_init( BUF* p_buf, void* buf, int buffer_size /*И т.д.*/); // Полезные функции, например void buf_clear( BUF* p_buf ) { memset( p_buf -> buf, 0, p_buf -> buf_size ); } и т.д. Лично я в последнее время стараюсь неукоснительно следовать этому подходу, и я заметил, что так совершаешь гораздо меньше ошибок. P.S. Мне могут указать, что можно сразу использовать С++ и не парится. Если у вас такой вопрос возник, то скомпилируйте вашу программу с ключиком -S в разных компиляторах и обратите внимание на название функций в ассемблерном листинге. На мысли наводит?
- проблемы с памятью ;), DeadMustdie, 13:08 , 10-Фев-05 (5)
>Мне могут указать, что можно сразу использовать С++ и не парится. ЕслиВозникает. Жизнь слишком коротка, чтобы лишний раз париться :). >у вас такой вопрос возник, то скомпилируйте вашу программу с ключиком >-S в разных компиляторах и обратите внимание на название функций в >ассемблерном листинге. На мысли наводит? А не всё ли равно? Если по каким-то причинам нужно недекорированное имя, к нему всегда можно приписать extern "C".
|