Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Правильно ли так использовать функцию calloc?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
011119xx
Работаю в Keil ARM. Проект под STM32. Пытаюсь разобраться с файлом gif. Использую библиотеку libungif-4.1.4. Приведу только часть кода в которой возникла проблема:
Код
typedef unsigned char GifByteType;

typedef struct GifColorType
{
    GifByteType Red, Green, Blue;
} GifColorType;

typedef struct ColorMapObject
{
    int ColorCount;                        
    int BitsPerPixel;                    
    GifColorType *Colors;                
} ColorMapObject;

    ...............

    BitsPerPixel = 8;

    ColorMap = (ColorMapObject *)malloc(sizeof(ColorMapObject));        

    if(ColorMap == (ColorMapObject *) NULL)                             
    {
        FATFileClose(fd);                                                

        return 0;        
    }

    ColorMap->Colors = (GifColorType *)calloc(1 << BitsPerPixel, sizeof(GifColorType));    

    if(ColorMap->Colors == (GifColorType *) NULL)                         
    {
        free((ColorMapObject *)ColorMap);                                  
        FATFileClose(fd);                                                

        return 0;                                                        
    }

    ..........


В данном куске кода выделяется память под глобальную палитру. Выделить то надо всего 768 байт. Память по функции malloc выделяется. А вот по calloc нет. Первая мысль, которая возникла, это не хватает памяти. Но такое не может быть, так как на борту 96 кило памяти и ей просто некуда деться. И вторая мысль - неправильное использование функции calloc. Есть у кого какие соображения?
Idle
использование функции calloc - правильное
CODE
$ cat el.c
#include <stdlib.h>
#include <stdio.h>

typedef unsigned char GifByteType;

typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;

typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
GifColorType *Colors;
} ColorMapObject;

static const int BitsPerPixel = 8;

int main()
{
ColorMapObject *ColorMap = malloc(sizeof(ColorMapObject));
if(!ColorMap)
abort();

ColorMap->Colors = calloc(1 << BitsPerPixel, sizeof(GifColorType));
if(!ColorMap->Colors)
abort();

exit(EXIT_SUCCESS);
}
$ gcc el.c -std=gnu99 -Wall -o el
$ ./el
$
demiurg_spb
Принципиальная разница между calloc и malloc лишь только в том, что первая ещё и очищает выделяемую память (заполняет нулями).
011119xx
Цитата(Idle @ Oct 5 2011, 11:17) *
использование функции calloc - правильное

Не вижу принципиальных отличий вашего и "моего" варианта.
Idle
Цитата(011119xx @ Oct 5 2011, 09:39) *
Не вижу принципиальных отличий вашего и "моего" варианта.

их нет
Сергей Борщ
QUOTE (011119xx @ Oct 5 2011, 06:47) *
Первая мысль, которая возникла, это не хватает памяти. Но такое не может быть, так как на борту 96 кило памяти и ей просто некуда деться.
А всю ли свободную память вы в настройках Кейла отдали под кучу? Или же там по умолчанию стоит какой-нибудь 1К?
011119xx
Цитата(Сергей Борщ @ Oct 5 2011, 17:07) *
А всю ли свободную память вы в настройках Кейла отдали под кучу? Или же там по умолчанию стоит какой-нибудь 1К?

Так и есть, только не 1К, а 2К (сам когда то менял). Значит меняю на большее значение. Спасибо.
011119xx
Увеличил размер кучи, теперь с выделением памяти проблем нет.

Есть еще одна не понятная проблема. Для проверки расширения файла использую процедуру:
Код
int extcheck(char *s, char *match)
{              
    char tmp[5];
    uint8_t i;

    if(strlen(s) > 3)                                 
    {
        strncpy(tmp, s + strlen(s) - 4, 4);            
        tmp[4] = 0;                                 

        tolower(*tmp);                        
        if(strcmp(tmp, match) == 0)                     
            return 1;                                
    }
              
    return 0;                                        
}

Проблема в функции tolower. Не хочет она переводить символы из верхнего регистра в нижний. Пробовал вместо
Код
tolower(*tmp);

и так:
Код
for(i = 0; i < 4; i++)
    tolower(tmp[i]);

тоже не работает. В чем может быть проблема?
barabek
А так?

Код
for(i = 0; i < 4; i++)


     tmp[i]=tolower(tmp[i]);
Палыч
Параметр функции tolower является не строка, а символ. Возвращает эта функция букву в нижнем регистре, если это была латинская буква в верхнем регистре, иначе - то же значение. Для преобразования символов строки Вам необходимо оргинизовать простой цикл по свем символам этой строки.
demiurg_spb
Цитата(011119xx @ Oct 6 2011, 07:00) *
В чем может быть проблема?
В Вашем подходе к делу.
Вы бы хоть краем глаза на описание применяемой функции смотрели, всё было бы хорошо...
Ну и основы Си почитать нужно обязательно.
Как по Вашему функция получающая аргументом значение а не указатель может его изменить?
Ответ - никак.
Дальше включаем голову и понимаем, что если функция не в состоянии "глобально" изменить аргумент, то она возвращает результат своей деятельности, который вы игнорировали.
Ведь всё просто и логично.
011119xx
Можно ли в процессе отладки где-то посмотреть сколько байт реально занимает стек и куча? Точнее посмотреть сколько уже потрачено.
demiurg_spb
Цитата(011119xx @ Oct 10 2011, 14:48) *
Можно ли в процессе отладки где-то посмотреть сколько байт реально занимает стек и куча?
Можно всё. Про стек: смотреть на регистр-указатель стека.
Что касается кучи - можно залесть в исходники менеджера памяти и добавить debug-print или узнать адрес статической переменной счётчика этого менеджера и его мониторить через jtag (скорее всего там будет не просто переменная а более сложная структура). Как-то так.
Сергей Борщ
QUOTE (demiurg_spb @ Oct 10 2011, 14:15) *
Можно всё. Про стек: смотреть на регистр-указатель стека.
И от этого адреса смотреть содержимое памяти, предварительно забив ее какой-либо константой (можно и нулем). Там будет видно, сколько на стек клали другие функции и обработчики прерываний (если стек общий).
011119xx
Цитата(demiurg_spb @ Oct 10 2011, 17:15) *
... Что касается кучи - можно залесть в исходники менеджера памяти и добавить debug-print или узнать адрес статической переменной счётчика этого менеджера и его мониторить через jtag ...

Можно подробнее? Где исходник менеджера памяти?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.