The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
проблемы с памятью ;), !*! maverick, 08-Фев-05, 19:46  [смотреть все]
Я программирую под 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);

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

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

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




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

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