реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Правильно ли так использовать функцию calloc?
011119xx
сообщение Oct 5 2011, 03:47
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Работаю в 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. Есть у кого какие соображения?

Сообщение отредактировал 011119xx - Oct 5 2011, 03:48
Go to the top of the page
 
+Quote Post
Idle
сообщение Oct 5 2011, 05:17
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874



использование функции 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
$


Сообщение отредактировал Idle - Oct 5 2011, 05:21
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 5 2011, 05:27
Сообщение #3


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Принципиальная разница между calloc и malloc лишь только в том, что первая ещё и очищает выделяемую память (заполняет нулями).


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
011119xx
сообщение Oct 5 2011, 05:39
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Цитата(Idle @ Oct 5 2011, 11:17) *
использование функции calloc - правильное

Не вижу принципиальных отличий вашего и "моего" варианта.
Go to the top of the page
 
+Quote Post
Idle
сообщение Oct 5 2011, 06:21
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874



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

их нет
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 5 2011, 11:07
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
011119xx
сообщение Oct 5 2011, 11:28
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



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

Так и есть, только не 1К, а 2К (сам когда то менял). Значит меняю на большее значение. Спасибо.
Go to the top of the page
 
+Quote Post
011119xx
сообщение Oct 6 2011, 03:00
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Увеличил размер кучи, теперь с выделением памяти проблем нет.

Есть еще одна не понятная проблема. Для проверки расширения файла использую процедуру:
Код
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]);

тоже не работает. В чем может быть проблема?
Go to the top of the page
 
+Quote Post
barabek
сообщение Oct 6 2011, 03:54
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



А так?

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


     tmp[i]=tolower(tmp[i]);
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 6 2011, 04:05
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Параметр функции tolower является не строка, а символ. Возвращает эта функция букву в нижнем регистре, если это была латинская буква в верхнем регистре, иначе - то же значение. Для преобразования символов строки Вам необходимо оргинизовать простой цикл по свем символам этой строки.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 6 2011, 05:15
Сообщение #11


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(011119xx @ Oct 6 2011, 07:00) *
В чем может быть проблема?
В Вашем подходе к делу.
Вы бы хоть краем глаза на описание применяемой функции смотрели, всё было бы хорошо...
Ну и основы Си почитать нужно обязательно.
Как по Вашему функция получающая аргументом значение а не указатель может его изменить?
Ответ - никак.
Дальше включаем голову и понимаем, что если функция не в состоянии "глобально" изменить аргумент, то она возвращает результат своей деятельности, который вы игнорировали.
Ведь всё просто и логично.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
011119xx
сообщение Oct 10 2011, 10:48
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Можно ли в процессе отладки где-то посмотреть сколько байт реально занимает стек и куча? Точнее посмотреть сколько уже потрачено.

Сообщение отредактировал 011119xx - Oct 10 2011, 10:49
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 10 2011, 11:15
Сообщение #13


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(011119xx @ Oct 10 2011, 14:48) *
Можно ли в процессе отладки где-то посмотреть сколько байт реально занимает стек и куча?
Можно всё. Про стек: смотреть на регистр-указатель стека.
Что касается кучи - можно залесть в исходники менеджера памяти и добавить debug-print или узнать адрес статической переменной счётчика этого менеджера и его мониторить через jtag (скорее всего там будет не просто переменная а более сложная структура). Как-то так.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 10 2011, 11:53
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (demiurg_spb @ Oct 10 2011, 14:15) *
Можно всё. Про стек: смотреть на регистр-указатель стека.
И от этого адреса смотреть содержимое памяти, предварительно забив ее какой-либо константой (можно и нулем). Там будет видно, сколько на стек клали другие функции и обработчики прерываний (если стек общий).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
011119xx
сообщение Oct 11 2011, 01:28
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Цитата(demiurg_spb @ Oct 10 2011, 17:15) *
... Что касается кучи - можно залесть в исходники менеджера памяти и добавить debug-print или узнать адрес статической переменной счётчика этого менеджера и его мониторить через jtag ...

Можно подробнее? Где исходник менеджера памяти?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 12:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.01521 секунд с 7
ELECTRONIX ©2004-2016