URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5881
[ Назад ]

Исходное сообщение
"Проблемы с динамической памятью в С (?)"

Отправлено webs , 08-Ноя-06 09:08 
Здравствуйте! Возникла следуюшая проблема. Я сейчас пишу http-сервер под Linux на чистом С, и возникают неполадки с динамической памятью. Ниже приведён кусок файла заголовка, в котором объявлены все переменные,о которых пойдёт речь. Особенно прошу обратить внимание на структуру httpd, так как переменная именно этого типа является аргументом практически всех функций и коллектором всей информации, достигая размеров порядка 15-16 килобайт (проверено в дебаггере kdbg). В ней есть указатель variables на массив структур типа httpVar. В variables записываются данные из лог-файла. Дело в том, что до добавления данного указателя в структуру httpd всё было отлично, а потом стали возникать всякие непонятные вещи - при отладке во время записи очередной переменной в массив происходит стирание или искажение значений других элементов массива и переменных, с ним никак не связанных! Запись ведётся с помощью strcpy (пробовал memcpy и даже memmov!). Память для элементов массива, как и для всей переменной server типа httpd выделяется динамически с помощью malloc. Пробовал заранее указывать их размеры - то же самое! Единственное, что сама переменная server всё равно создаётся динамически, я просто не могу позволить себе тратить столько памяти почём зря, ведь приложение ещё и многозадачное, на тредах построено... И в другую переменную данные из лога не запишешь, вся структура проги построена на принципе одной глобальной переменной.
Советовали попробовать какой-то valgrind для слежки за памятью,у себя не нашёл,да и вряд ли поможет...
В той же функции для чтения из конфига при чтении из файла почему-то возникают сбои,не хочет работать замечательная функция fgets, а при единовременном чтении в буфер происходит искажение находящихся в нём данных по мере продвижения по нему и ЗАПИСИ ДАННЫХ в переменную variables!!!
Я только недавно стал серьёзно разбираться с языком С, был на седьмом небе от возможностей арифметики указателей и динамической памяти (после Паскаля-то!),и вот на тебе - такая ерунда...
Отсылал другу тестить - у него FreeBSD стоит, говорит, как будто всё без ошибок, тогда вообще всё странно... Но доверять ему не очень можно! :)
У меня SuSE Linux 9.2, ещё пробовал на Debian 3.0 - то же самое...
Компилер gcc вроде 3 версии...

В общем,такие дела! Идеи, мысли, предложения - очень прошу помочь!
Спасибо заранее!


/***********************************************************************
** Type Definitions
*/

typedef    struct {
    int    method,
        contentLength,
        authLength;
    char    path[HTTP_MAX_URL],
        host[HTTP_MAX_URL],
        userAgent[HTTP_MAX_URL],
        referer[HTTP_MAX_URL],
        ifModified[HTTP_MAX_URL],
        contentType[HTTP_MAX_URL],
        authUser[HTTP_MAX_AUTH],
        authPassword[HTTP_MAX_AUTH];
} httpReq;


typedef struct _httpd_var{
    char    *name,
        *value;
    struct    _httpd_var     *nextValue,
                *nextVariable;
} httpVar;

typedef struct _httpd_content{
    char    *name;
    int    type,
        indexFlag;
    void    (*function)();
    char    *data,
        *path;
    int    (*preload)();
    struct    _httpd_content     *next;
} httpContent;

typedef struct {
    int        responseLength;
    httpContent    *content;
    char        headersSent,
            headers[HTTP_MAX_HEADERS],
            response[HTTP_MAX_URL],
            contentType[HTTP_MAX_URL];
} httpRes;


typedef struct _httpd_dir{
    char    *name;
    struct    _httpd_dir *children,
            *next;
    struct    _httpd_content *entries;
} httpDir;


typedef struct ip_acl_s{
        int     addr;
        char    len,
                action;
        struct  ip_acl_s *next;
} httpAcl;


typedef struct {
    int    port,
        serverSock,
        clientSock,
        readBufRemain,
        startTime;
    char    clientAddr[HTTP_IP_ADDR_LEN],
        fileBasePath[HTTP_MAX_URL],
        readBuf[HTTP_READ_BUF_LEN + 1],
        *host,
        *readBufPtr;
    httpReq    request;
    httpRes response;
    httpVar    *variables;
    httpDir    *content;
    httpAcl    *defaultAcl;
    FILE    *accessLog,
        *errorLog;
    void    (*errorFunction304)(),
        (*errorFunction403)(),
        (*errorFunction404)();
    struct  {
            char name[HTTP_MAX_SET_SIZE];
            char value[HTTP_MAX_SET_SIZE];
        } settings[NUMSET];
    char    *sfile;
    char    *cfile;
} httpd;


Содержание

Сообщения в этом обсуждении
"Проблемы с динамической памятью в С (?)"
Отправлено dsl , 08-Ноя-06 09:19 
скомпилируй проект с debug опциями и для отлова memory leak используй valgrind

"Проблемы с динамической памятью в С (?)"
Отправлено Сергей , 08-Ноя-06 14:42 
Ох! По приведенным выше структурам сказать что-то определнное невозможно. Единсвтенный совет, воспользоваться valgrind'ом (как было предложено выше).. Он тебе может явно сказать строчки кода где ты обращаешся в чужую память и выходишь за границы массивов.

> Я только недавно стал серьёзно разбираться с языком С, был на седьмом небе от
> возможностей арифметики указателей и динамической памяти (после Паскаля-то!),и
> вот на тебе - такая ерунда...

Это не ерунда ... Указатели это мощнейший инструмент, но в неумелых руках опасен как та бомба в анекдоте про мартышек =)

Успехов!


"Проблемы с динамической памятью в С (?)"
Отправлено pup , 08-Ноя-06 18:44 
>Советовали попробовать какой-то valgrind для слежки за памятью,у себя не нашёл,да и
>вряд ли поможет...

поверь, поможет. может не 100%, но... ты, короче, попробуй. сам поймёшь. найди valgrind в пакетах к своей системе и поставь. если не найдёшь в пакетах, скачай сорцы, скомпиляй и поставь.


"Проблемы с динамической памятью в С (?)"
Отправлено Niam , 08-Ноя-06 19:00 
А при работе со строками не забываешь выделять память поду нулевой символ??
Это очень распространенная ошибка!