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

 
 
> Использование realloc()
koluna
сообщение Jun 25 2009, 14:05
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Здравствуйте!

WinAVR 20071221.
scmRTOS 3.05.
ATmega48.

Выделяю память в цикле (последовательно добавляю по одному байту).

Код
...
unsigned int* Buffer_Size;
unsigned char* Buffer;
...
// В цикле.
(*Buffer_Size)++;
Buffer = (unsigned char*) realloc((unsigned char*)Buffer, *Buffer_Size);
...


При выделении на третьем байте realloc возвращает 0 почему?
Память кончилась? smile.gif

Благодарю заранее!

Когда делаю, допустим, так:
Код
...
unsigned char* PBuff;
...
PBuff = (unsigned char*) malloc(8);

то всё нормально...


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SysRq
сообщение Jun 25 2009, 20:53
Сообщение #2


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Из такого куска кода как-то не ясно начальное значение (*Buffer_Size). Может быть действительно еще пара байт свободных байт остается...
Go to the top of the page
 
+Quote Post
koluna
сообщение Jun 26 2009, 06:15
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Цитата(SysRq @ Jun 25 2009, 23:53) *
Из такого куска кода как-то не ясно начальное значение (*Buffer_Size). Может быть действительно еще пара байт свободных байт остается...


Перед началом выделения:

Код
*Buffer_Size = 0;


Код
...
    unsigned char* PBuff;
    unsigned int Size_Buff;
...
    Res = USART.Read(PBuff, &Size_Buff);
    USART.Write(PBuff, Size_Buff);
....
TStatus_Op TUSART_S::Read(unsigned char* Buffer, unsigned int* Buffer_Size)
{
    unsigned char ParityBit; // Временная переменная для хранения значения 9-го бита принятого по USART байта данных.
    unsigned int i;
    unsigned char Event_Result;

    Enable_RXD_Int(); // Разрешение прерывания по окончании передачи байта.
    *Buffer_Size = 0;
    i = 0;
    do
    {
        if (*Buffer_Size == 0) {Event_Result = ByteIsReceived_Event.Wait(0);}
        else {Event_Result = ByteIsReceived_Event.Wait(RD_TimeOut);};

        if (!Event_Result)
        {
// Тайм-аут при приёме байта.
            Disable_RXD_Int(); // Запрещение прерывания по окончании приёма байта.
            return SO_READ_TIME_OUT;
        };
        (*Buffer_Size)++;
        Buffer = (unsigned char*) realloc((unsigned char*)Buffer, *Buffer_Size); // Выделение участка памяти.
// Проверка успешности выделения участка памяти под буфер приёмника.
        if (!Buffer)
        {
// Ошибка выделения участка памяти.
            Disable_RXD_Int(); // Запрещение прерывания по окончании приёма байта.
            return SO_MEMORY_NOT_ALLOCATED;
        };
        ParityBit = Get_Parity_Bit();
// Извлечение очередного байта из регистра данных USART и загрузка его в буфер приёмника.
        *(Buffer + i) = Read_Byte();
        i++;
        Enable_RXD_Int(); // Разрешение прерывания по окончании передачи байта.
    }
    while (*Buffer_Size < 7);
    Disable_RXD_Int(); // Запрещение прерывания по окончании приёма байта.
    return SO_OPERATION_COMPLETE;
...
};


Памяти, я думаю, хватает...
Следующий код работает нормально.

Код
...
    unsigned char* PBuff;
    unsigned int Size_Buff;
...
    Size_Buff = 26;
    PBuff = (unsigned char*) malloc(Size_Buff);
    Res = USART.Read(PBuff, (const unsigned int) Size_Buff);
    USART.Write(PBuff, Size_Buff);
    free(PBuff);
...
TStatus_Op TUSART_S::Read(unsigned char* Buffer, const unsigned int Buffer_Size)
{
    unsigned char Event_Result;

    for (unsigned int i = 0; i < Buffer_Size; i++)
    {
        Enable_RXD_Int(); // Разрешение прерывания по окончании передачи байта.
        if (i == 0) {Event_Result = ByteIsReceived_Event.Wait(0);}
        else {Event_Result = ByteIsReceived_Event.Wait(RD_TimeOut);};
        if (!Event_Result) {return SO_READ_TIME_OUT;}; // Тайм-аут при приёме байта.
// Извлечение очередного байта из регистра данных USART и загрузка его в буфер приёмника.
        *(Buffer + i) = Read_Byte();
    };
    return SO_OPERATION_COMPLETE;
};
...


Смысл-то в том, чтобы менять размер буфера при приёме...
Т. е., конечно, проще и надёжнее - выделить память под буфер на N байт сразу и прочитать эти N байт.
А ещё проще и надёжнее - использовать обычный массив.
А если N неизвестно или известно, что оно не более M?
Выделять память по буфер M байт не хочется... неэкономично как-то и некрасиво smile.gif

Программа работает совместно с scmRTOS.
Так что процесс ждёт эвента ByteIsReceived_Event, свидетельствующего о получении байта по USART.
Эвент сигналится в прерывании по приёму...

Возможно, решение проблемы здесь: http://bytes.com/groups/c/603687-problem-realloc
Надо проверить smile.gif


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 26 2009, 06:18
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(n_bogoyavlensky @ Jun 26 2009, 09:00) *
Выделять память по буфер M байт не хочется... неэкономично как-то и некрасиво smile.gif

Вы страшно далеки от представления, что такое realloc о его "'экономичности" и способах (отданных на откуп компилятору/системе) реализации и САМОЙ ВОЗМОЖНОСТИ сколь-нибудь хоть для чего-нибудь пригодной реализации на AVR. То, что Вы накропали с realloc это чистое безумие. Впрочем, все остальное не лучше sad.gif.
Цитата
При выделении на третьем байте realloc возвращает 0 почему?
Память кончилась?

Да, та минимальная порция (очевидно 4 байта в конкретной реализации), которую получили при первом запросе КОНЧИЛАСЬ.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- n_bogoyavlensky   Использование realloc()   Jun 25 2009, 14:05
|- - n_bogoyavlensky   Цитата(zltigo @ Jun 26 2009, 09:18) Вы ст...   Jun 26 2009, 06:33
- - SysRq   Попробуйте инициализировать PBuff (присвоить NULL)...   Jun 26 2009, 06:44
|- - n_bogoyavlensky   Цитата(SysRq @ Jun 26 2009, 09:44) Попроб...   Jun 26 2009, 07:33
- - SysRq   Значит zltigo прав. Разбирайтесь сколько отведено ...   Jun 26 2009, 08:45
|- - n_bogoyavlensky   Цитата(SysRq @ Jun 26 2009, 11:45) Значит...   Jun 26 2009, 12:54
- - DpInRock   Я в Сях ничего не понимаю, но ради развлечения не ...   Jun 26 2009, 15:16
|- - n_bogoyavlensky   Цитата(DpInRock @ Jun 26 2009, 18:16) Я в...   Jun 29 2009, 06:08
|- - sergeeff   Цитата(n_bogoyavlensky @ Jun 29 2009, 10...   Jun 29 2009, 06:57
|- - Сергей Борщ   Цитата(n_bogoyavlensky @ Jun 29 2009, 09...   Jun 29 2009, 08:16
- - Сергей Борщ   Цитата(n_bogoyavlensky @ Jun 25 2009, 17...   Jun 26 2009, 15:44
- - SysRq   Гм. Я ж выше вам написал, что указатель проинициал...   Jun 29 2009, 08:30
- - n_bogoyavlensky   Цитата(SysRq @ Jun 29 2009, 11:30) Гм. Я ...   Jun 29 2009, 08:35


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

 


RSS Текстовая версия Сейчас: 30th June 2025 - 04:34
Рейтинг@Mail.ru


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