The OpenNET Project / Index page

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

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

"проблемы с памятью ;)" 
Сообщение от maverick emailИскать по авторуВ закладки on 08-Фев-05, 19:46  (MSK)
Я программирую под Linux (2.4.22) на си, используя компилятор gcc 3.4.3
Посоветуйте самый безглючный способ инициализации памяти:
1) объявить static char *buffer; затем в main(): buffer = (char *) calloc(SIZE, 1); а в подключаемых файлах писать extern char *buffer;

2) объявить в каждом из файлов свой static char *buffer; в каждой функции
писать buffer = (char *) calloc(SIZE, 1); а затем free(buffer);

Просто блин эти сегфолты действуют на нервы...

И ещё вопрос: может ли возникать сегфолт при работе с памятью если ядро старое? (может быть, вопрос глупейший)

  Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

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

1. "проблемы с памятью ;)" 
Сообщение от DeadMustdie emailИскать по авторуВ закладки(??) on 09-Фев-05, 11:02  (MSK)
>Я программирую под 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'ами.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "проблемы с памятью ;)" 
Сообщение от maverick emailИскать по авторуВ закладки on 09-Фев-05, 20:47  (MSK)

>Не должно даже линковаться. Переменные класса static не видны за
>пределами модуля трансляции (в простейшем случае - c-файла), в
>котором они объявлены.
>

То есть как это не видны? Видны. Иначе зачем вообще такая фича как
extern ?

>>
>> 2) объявить в каждом из файлов свой static char *buffer; в
>>каждой функции
>>писать buffer = (char *) calloc(SIZE, 1); а затем free(buffer);
>
>Лучше по мере надобности память в оных функциях выделять, а по
>окончании оной надобности - освобождать.
>

Допустим мне надо создать в программе три часто исплользуемых буфера.
Дак что же, мне придётся тогда в каждой подпрограмме их объявлять, аллокейтить, юзать, а потом освобождать? Как-то гиморно.. Неужели нельзя сделать всё первым способом?

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "проблемы с памятью ;)" 
Сообщение от Xenu emailИскать по авторуВ закладки on 09-Фев-05, 22:01  (MSK)
>
>>Не должно даже линковаться. Переменные класса static не видны за
>>пределами модуля трансляции (в простейшем случае - c-файла), в
>>котором они объявлены.
>>
>
>То есть как это не видны? Видны. Иначе зачем вообще такая фича
>как
>extern ?
Как это возможно, что static переменная объявленная в одном файле видно из другого файла.
Не покажите ли что линкер напечатал при собирании такого кода.

extern служит не для того что бы static переменные в другом файле использовать.

>>>
>>> 2) объявить в каждом из файлов свой static char *buffer; в
>>>каждой функции
>>>писать buffer = (char *) calloc(SIZE, 1); а затем free(buffer);
>>
>>Лучше по мере надобности память в оных функциях выделять, а по
>>окончании оной надобности - освобождать.
>>
>
>Допустим мне надо создать в программе три часто исплользуемых буфера.
>Дак что же, мне придётся тогда в каждой подпрограмме их объявлять, аллокейтить,
>юзать, а потом освобождать? Как-то гиморно.. Неужели нельзя сделать всё первым
>способом?
объявите 3 буфера или один. но только обращайтесь к ним через функции доступа и не пишите напрямую в буфера из других мест.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "проблемы с памятью ;)" 
Сообщение от dimus Искать по авторуВ закладки(??) on 10-Фев-05, 12:36  (MSK)
Я пришел к выводу, что оптимальным вариантом во многих случаях является использование подхода, подобного классам в С++. Напишите семейство функций, внутри которых идет работа с этим буфером, как с ЗАКРЫТЫМ объектом. Пусть ничто из внешнего мира не обращается к нему иначе, чем через них. Тогда если ошибки и возникнут, их можно будет очень легко отследить и ликвидировать.

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 в разных компиляторах и обратите внимание на название функций в ассемблерном листинге. На мысли наводит?

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "проблемы с памятью ;)" 
Сообщение от DeadMustdie emailИскать по авторуВ закладки(??) on 10-Фев-05, 13:08  (MSK)
>Мне могут указать, что можно сразу использовать С++ и не парится. Если

Возникает. Жизнь слишком коротка, чтобы лишний раз париться :).

>у вас такой вопрос возник, то скомпилируйте вашу программу с ключиком
>-S в разных компиляторах и обратите внимание на название функций в
>ассемблерном листинге. На мысли наводит?

А не всё ли равно? Если по каким-то причинам нужно недекорированное
имя, к нему всегда можно приписать extern "C".

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "проблемы с памятью ;)" 
Сообщение от dimus Искать по авторуВ закладки(??) on 10-Фев-05, 13:36  (MSK)
Из ассемблера?
  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "проблемы с памятью ;)" 
Сообщение от DeadMustdie emailИскать по авторуВ закладки(??) on 10-Фев-05, 16:35  (MSK)
>Из ассемблера?

extern "C" int myIntValForAsmAccess;
extern "C" int myFyncForAsmAccess(int a, int b);

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх


Архив | Удалить

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




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

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