|
Помогите разобраться с динамическим выделением памяти, Как пристроить другой sbrk ??? |
|
|
|
Dec 21 2006, 13:45
|
Участник

Группа: Новичок
Сообщений: 25
Регистрация: 10-04-06
Пользователь №: 15 981

|
Пишу программу для LPC2214 с внешней SRAM, разместил область стека во внуреннем ОЗУ, а кучу во внешнем, но при использовании функций динамического выделения памяти прога зависает. Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка ENOMEM. После поисков в internet и в документации к Newlib, стало ясно что надо написать другой вариант фунции sbrk, но при этом возникли вопросы: 1. как называть новую переопределяемую функцию (в разных местах ее называют как sbrk, _sbrk, _sbrk_r, может еще как-нибудь) 2. как пристроить эту новую функцию, чтобы она заменила существующую библиотечную и линкер бы не ругался
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
Dec 21 2006, 14:28
|
Участник

Группа: Новичок
Сообщений: 25
Регистрация: 10-04-06
Пользователь №: 15 981

|
Цитата(zltigo @ Dec 21 2006, 13:53)  Цитата(Alexey75 @ Dec 21 2006, 12:45)  Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка ENOMEM.
Абсолютно все равно где находится стек. Что-то у Вас с причиной другое совсем. Я делал пошаговое выполнение, так вот в функции _sbrk проверяется, чтобы выделяемая область памяти не попадала на стек: caddr_t _sbrk (int incr) { extern char end asm ("end"); /* Defined by the linker. */ static char * heap_end; char * prev_heap_end; if (heap_end == NULL) heap_end = & end; prev_heap_end = heap_end; if (heap_end + incr > stack_ptr) { /* Some of the libstdc++-v3 tests rely upon detecting out of memory errors, so do not abort here. */ #if 0 extern void abort (void); _write (1, "_sbrk: Heap and stack collision\n", 32); abort (); #else errno = ENOMEM; return (caddr_t) -1; #endif } heap_end += incr; return (caddr_t) prev_heap_end; }
|
|
|
|
|
Dec 21 2006, 15:04
|

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

|
Цитата(Alexey75 @ Dec 21 2006, 13:28)  Я делал пошаговое выполнение, так вот в функции _sbrk Для начала Вы написали следующее: Цитата при использовании функций динамического выделения памяти прога зависает. Между написанным и неработоспособностью некой _sbrk() - изменяющей размер хипа и не имеющей, отношения к привычному системному вызову sbrk() есть разница. А есть-ли вообще необходимость на ходу менять размер heap? Что там за границей у Вас находится? "Ничего"? Так отдайте сразу все под heap. Цитата 2. как пристроить эту новую функцию, чтобы она заменила существующую библиотечную и линкер бы не ругался Ну а если желаете создать иллюзию изменения - то просто напишите свою выкинув контроль и она будет молча использоваться вместо библиотечной.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 21 2006, 15:30
|
Участник

Группа: Новичок
Сообщений: 25
Регистрация: 10-04-06
Пользователь №: 15 981

|
Я видимо не совсем ясно выразился, когда задавал вопрос. Вобщем то у меня нет желания делать какие-то навороты по управлению памятью. Проблема возникает когда я размещаю стек во внутренней памяти LPC2214, а heap во внешней (большего размера). Если разместить heap ниже стека то все работает нормально, уже проверил. Просто хотелось бы чтобы стек находился в быстрой внутренней памяти, но там мало места, чтобы размещать там и heap.
По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция.
Сообщение отредактировал Alexey75 - Dec 21 2006, 15:36
|
|
|
|
|
Dec 21 2006, 15:40
|

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

|
Цитата(Alexey75 @ Dec 21 2006, 14:30)  Вобщем то у меня нет желания делать какие-то навороты по управлению памятью. Проблема возникает когда я размещаю стек во внутренней памяти LPC2214, а heap во внешней (большего размера). Если разместить heap ниже стека то все работает нормально, уже проверил. Просто хотелось бы чтобы стек находился в быстрой внутренней памяти, но там мало места, чтобы размещать там и heap. Все пожелания абсолютно логичны. Проблема не понятна, ибо _sbrk() это уже перераспледеление размера heap. Или они ее и для инициализации размера (я не в курсе) heap используют? В общем если так, то просто выкиньте "контроль" и поместите результат в свой проект. Цитата По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция. Даже затрудняюсь предположить, что можно сделать "не так"
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 21 2006, 16:01
|
Участник

Группа: Новичок
Сообщений: 25
Регистрация: 10-04-06
Пользователь №: 15 981

|
Цитата(zltigo @ Dec 21 2006, 15:40)  Цитата По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция.
Даже затрудняюсь предположить, что можно сделать "не так"  Не хотелось бы задавать глупые вопросы, но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции.
|
|
|
|
|
Dec 21 2006, 16:06
|

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

|
Цитата(Alexey75 @ Dec 21 2006, 15:01)  но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции. Третий раз пишу - написать свою одноименную и все. Не представляю, по каким причинам сие может не сработать.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 21 2006, 16:10
|
Участник

Группа: Новичок
Сообщений: 25
Регистрация: 10-04-06
Пользователь №: 15 981

|
Цитата(zltigo @ Dec 21 2006, 16:06)  Цитата(Alexey75 @ Dec 21 2006, 15:01)  но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции.
Третий раз пишу - написать свою одноименную и все. Не представляю, по каким причинам сие может не сработать. С третьего раза я понял о чем вы говорите  , буду разбираться с компилятором
|
|
|
|
|
Dec 21 2006, 18:00
|

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

|
Цитата(Сергей Борщ @ Dec 21 2006, 16:38)  Если файл в котором будете определять функцию компилится в режиме C++, то надо функцию объявить с extern "C", иначе она получит другое "С++ное" внутреннее имя и, соответственно, не заменит библиотечную. А что производители компиляторов уже начали писать библиотечные хидеры без extern "С"  ? Хотя конечно если не включить готовый хидер и наплевать на вопли об отсутствии прототипа, то добиться вышеописанного можно
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 22 2006, 15:36
|
Участник

Группа: Новичок
Сообщений: 25
Регистрация: 10-04-06
Пользователь №: 15 981

|
Проблема решилась, когда я подменил не функцию _sbrk, а функцию _sbrk_r, файл _sbrk_r.c был взят из newlib-lpc_rel_5a. В результате линкер перестал ругаться, что встретил два определения функции и нормально подменил библиотечную функцию.
Сообщение отредактировал Alexey75 - Dec 22 2006, 15:41
|
|
|
|
|
Dec 22 2006, 20:43
|

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

|
Цитата(zltigo @ Dec 22 2006, 17:55)  Цитата(Сергей Борщ @ Dec 22 2006, 16:20)  Например я постоянно использую свое определение extern "C" __low_level_init(), но при этом никакой дополнительный хидер в main.cpp не включаю.
__low_level_init() не есть библиотечная функция а просто IARовский прибамбас, посему вполне логично для него отсутствует прототип в библиотечных хидерах и IAR выдает просто болванку в которой все в одном флаконе с хидером. Описывать-же "свои" прототипы для стандартных библиотечных функций есть безобразие. Прототипы = объявления, да. Но речь шла об определении = теле функции. Если по имени, параметрам и типу возвращаемого значения функция совпадает с библиотечной, то не вижу причины перед ее определением включать хидер с объявлением. Например в таком предельном случае когда под определение этой функции выделен отдельный исходный файл.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 22 2006, 20:59
|

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

|
Цитата(Сергей Борщ @ Dec 22 2006, 19:43)  Если по имени, параметрам и типу возвращаемого значения функция совпадает с библиотечной, то не вижу причины перед ее определением включать хидер с объявлением. Вот для того, дабы абсолютно гарантированно выполнялось "параметрам и типу возвращаемого значения функция совпадает с библиотечной" и следует включать штатные библиотечные хидеры. Данный вырожденный случай: Цитата Например в таком предельном случае когда под определение этой функции выделен отдельный исходный файл. абсолютно правилен и допустим и конкретно применен IARом для уже поминаемого ранее __low_level_init() только вот к библиотекам не имеющим по определению файла с исходным текстом ну никакого отношения не имеет. Для библиотек отсутствие отдельного файла хидера невозможно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 22 2006, 23:52
|

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

|
Цитата(zltigo @ Dec 22 2006, 19:59)  Цитата(Сергей Борщ @ Dec 22 2006, 19:43)  Если по имени, параметрам и типу возвращаемого значения функция совпадает с библиотечной, то не вижу причины перед ее определением включать хидер с объявлением.
Вот для того, дабы абсолютно гарантированно выполнялось "параметрам и типу возвращаемого значения функция совпадает с библиотечной" и следует включать штатные библиотечные хидеры. Тут трудно не согласиться, хотя для С++ функии отличающиеся типом и/или количеством параметров суть есть разные функции. Так что 100% гарантии давать не должно. Правда не знаю, относится ли это к функциям с квалификатором extern "C"
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 23 2006, 00:45
|

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

|
Цитата(Сергей Борщ @ Dec 22 2006, 22:52)  для С++ функии отличающиеся типом и/или количеством параметров суть есть разные функции. Да в плюсах имя функции уродуется по полной программе и отражает, и параметры, и возвращаемое значение. Пару раз приходилось С++ функцию вызывать из ASM - разборки по полной программе  Цитата Так что 100% гарантии давать не должно. ??? Точнее, надо полагать не нуждается в прототипе для 100% гарантии. Цитата Правда не знаю, относится ли это к функциям с квалификатором extern "C" Не относится, к счастью  - обычное добавление подчеркивания. Зато и без прототипа работать моветон  . И при ошибке в прототипе проблемы по полной программе. Библиотечные функции естественно в "C" а не "C++" стиле со всеми вытекающими удобствами и последствиями.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|