Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с malloc()

7.2K
28 июля 2008 года
polaroid
94 / / 05.07.2008
Помогите пожалуйста. Не могу никак усмирить malloc() realloc(). Задача такая - динамически выделять буфер и читать в него сообщения на сокете. Когда делаю malloc сразу на 2мб, без реаллоков, тогда все работает, как часы. А когда делаю так, как внизу, тогда программа ведет себя неадекватно. Вообщем проблемное место выделил красным:
З.Ы ЯЗЫК С (НЕ С++) Платформа Windows

Код:
void thread()
{
    SOCKET s = 0;
    int rcv_size, snd_size, p_size, size = sizeof(int);
    long ptr = 0, bytesRead = 0;
    char *send_str;

    char *szPage;

    char substring[MAX_STR];

    int exp_count = 0;
    int ovector[VECT_SIZE];
    int matches = 0;

    int i = 0,j = 0;
    char counter[10];

    getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&rcv_size, &size);
    getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&snd_size, &size);

    for (j=startCount; j<=stopCount; j++) {
        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        connect(s, (SOCKADDR*)&sin_remote, sizeof(sin_remote));

        if ((send_str = malloc(snd_size)) == NULL) {
            error(10);
        }

        strcpy(send_str, "GET http://");
        strcat(send_str, host);
        sprintf(counter, "%d", j);
        strcat(send_str, substr(query, "{ID}",counter));
        strcat(send_str, " HTTP/1.0\nHost: ");
        strcat(send_str, host);
        strcat(send_str, "\nUser-Agent: ");
        strcat(send_str, agent);
        strcat(send_str, "\nAccept: */*\nAccept-Language: en-US\n\n\n");
   
        send(s, send_str, (int)strlen(send_str)-1, 0);
        free(send_str);

        if ((szPage = malloc(rcv_size)) == NULL)
            error(10);

        p_size = rcv_size;

        [COLOR="Red"]while (1) {
            if ((bytesRead = recv(s, szPage+ptr, rcv_size, 0)) <= 0)
                break;

            ptr += bytesRead;
            p_size += rcv_size;

            if ((szPage = realloc(szPage, p_size)) == NULL)
                error(10);
        }[/COLOR]

        matches = pcre_exec(re, NULL, (char*)szPage, ptr, 0, 0, ovector, 300);

        for (i=0; i<=matches; i++) {
            memset(substring, 0, MAX_STR);
            pcre_copy_substring((char*)szPage, ovector, matches, i, substring, MAX_STR);
            fprintf(out, "%s\n", substring);
        }

        free(szPage);
        closesocket(s);
    }
}
9.3K
28 июля 2008 года
iridum
175 / / 26.08.2007
Цитата: polaroid
А когда делаю так, как внизу, тогда программа ведет себя неадекватно.



Всмысле неадекватно....? А вообще realloc не стоит часто делать, на производительности может сказатся.
realloc adjusts the size of the allocated block to size, copying the contents to a new location if necessary.

535
29 июля 2008 года
Нездешний
537 / / 17.01.2008
Код:
p_size = rcv_size;

while (1)
{
    if ((bytesRead = recv(s, szPage+ptr, rcv_size, 0)) <= 0)
                break;

    ptr += bytesRead;
    p_size += rcv_size;

    if ((szPage = realloc(szPage, p_size)) == NULL)
                error(10);
}


Переменные ptr и p_size в некотором смысле дублируют друг друга.
Память всегда довыделяется блоками по rcv_size, но при bytesRead < rcv_size предыдущий блок используется не до конца. Накапливается неиспользуемая память размером по (rcv_size - bytesRead) с каждой итерации.
Хотя косяк несмертельный вроде бы :)

Поконкретнее, в чем "неадекватность"?
7.2K
29 июля 2008 года
polaroid
94 / / 05.07.2008
Неадекватность в том, что буфер szPage может заполнятся, а может не заполнятся. Я пока не понял из-за чего. Но если я не использую реаллок и делаю сразу malloc(какой-то там размер, например 1мб) и потом memset(), то все работает. Просто проблема в том, что заведомо неизвестно, какое количество данных придет на сокет. Поэтому я и прибегнул к такой конструкции как malloc, realloc. Но, похоже это действительно накладно. Как я понял, реализация malloc в win32 использует HeapAlloc. Может тогда попробовать заюзать VirtualAllocEx() ??
9.3K
29 июля 2008 года
iridum
175 / / 26.08.2007
Лучше выдели alloc сразу 0.5 метра, если в них не вложишься realloc до 1 метра, и т. д., е если наоборот чрезмерно будет тоже realloc - и зделано будет красивее, и от глюка скорее всего избавишься....
7.2K
29 июля 2008 года
polaroid
94 / / 05.07.2008
Ок, попробую так
7.2K
29 июля 2008 года
polaroid
94 / / 05.07.2008
Вообщем сделал, вроде работает, но отсюда еще один вопрос. Мне нужно сделать приложение в несколько потоков (CreateThread) и в качестве потока использовать эту процедуру, но возникает проблема. Malloc() не может выделить память. Кто знает что делать?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог