Перейти к содержанию
    

Помогите разобраться с динамическим выделением памяти

Пишу программу для LPC2214 с внешней SRAM, разместил область стека во внуреннем ОЗУ, а кучу во внешнем, но при использовании функций динамического выделения памяти прога зависает. Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка ENOMEM. После поисков в internet и в документации к Newlib, стало ясно что надо написать другой вариант фунции sbrk, но при этом возникли вопросы:

1. как называть новую переопределяемую функцию (в разных местах ее называют как sbrk, _sbrk, _sbrk_r, может еще как-нибудь)

2. как пристроить эту новую функцию, чтобы она заменила существующую библиотечную и линкер бы не ругался

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка ENOMEM.

Абсолютно все равно где находится стек. Что-то у Вас с причиной другое совсем.

И какое отношение sbrk() к описанной проблеме при попытке динамического выделения памяти вообще имеет. А как Вы вообще представляете реаллокацию памяти на контроллерах класса ARM7?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как оказалось проблема в том что куча находится выше указателя стека и из-за этого выдается ошибка 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;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я делал пошаговое выполнение, так вот в функции _sbrk

Для начала Вы написали следующее:

при использовании функций динамического выделения памяти прога зависает.

Между написанным и неработоспособностью некой _sbrk() - изменяющей размер хипа и не имеющей, отношения к привычному системному вызову sbrk() есть разница.

 

А есть-ли вообще необходимость на ходу менять размер heap? Что там за границей у Вас находится?

"Ничего"? Так отдайте сразу все под heap.

2. как пристроить эту новую функцию, чтобы она заменила существующую библиотечную и линкер бы не ругался

Ну а если желаете создать иллюзию изменения - то просто напишите свою выкинув контроль и она будет молча использоваться вместо библиотечной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я видимо не совсем ясно выразился, когда задавал вопрос. Вобщем то у меня нет желания делать какие-то навороты по управлению памятью. Проблема возникает когда я размещаю стек во внутренней памяти LPC2214, а heap во внешней (большего размера). Если разместить heap ниже стека то все работает нормально, уже проверил. Просто хотелось бы чтобы стек находился в быстрой внутренней памяти, но там мало места, чтобы размещать там и heap.

 

По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция.

Изменено пользователем Alexey75

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вобщем то у меня нет желания делать какие-то навороты по управлению памятью. Проблема возникает когда я размещаю стек во внутренней памяти LPC2214, а heap во внешней (большего размера). Если разместить heap ниже стека то все работает нормально, уже проверил. Просто хотелось бы чтобы стек находился в быстрой внутренней памяти, но там мало места, чтобы размещать там и heap.

Все пожелания абсолютно логичны. Проблема не понятна, ибо _sbrk() это уже перераспледеление размера heap. Или они ее и для инициализации размера (я не в курсе) heap используют? В общем если так, то просто выкиньте "контроль" и поместите результат в свой проект.

По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция.

Даже затрудняюсь предположить, что можно сделать "не так" :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По большому счету я понял что делать, у меня просто не получилось сделать так, чтобы при компиляции вместо библиотечной функции использовалась измененная мной функция.

Даже затрудняюсь предположить, что можно сделать "не так" :(

 

Не хотелось бы задавать глупые вопросы, но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции.

Третий раз пишу - написать свою одноименную и все. Не представляю, по каким причинам сие может не

сработать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но как сделать, чтобы компилятор не обращал внимание на существование библиотечной функции, а брал бы новый вариант функции.

Третий раз пишу - написать свою одноименную и все. Не представляю, по каким причинам сие может не

сработать.

С третьего раза я понял о чем вы говорите :) , буду разбираться с компилятором

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С третьего раза я понял о чем вы говорите :) , буду разбираться с компилятором
Если файл в котором будете определять функцию компилится в режиме C++, то надо функцию объявить с extern "C", иначе она получит другое "С++ное" внутреннее имя и, соответственно, не заменит библиотечную.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если файл в котором будете определять функцию компилится в режиме C++, то надо функцию объявить с extern "C", иначе она получит другое "С++ное" внутреннее имя и, соответственно, не заменит библиотечную.

А что производители компиляторов уже начали писать библиотечные хидеры без extern "С" :)?

Хотя конечно если не включить готовый хидер и наплевать на вопли об отсутствии прототипа, то добиться вышеописанного можно :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Когда идет инициализация стеков и кучи, внешняя память не подключена к процессору.

На сколько я помню, кроме контроллера внешней памяти еще необходимо соответственно настраивать совмещенные с шиной памяти порты.

Может в этом проблема

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема решилась, когда я подменил не функцию _sbrk, а функцию _sbrk_r, файл _sbrk_r.c был взят из newlib-lpc_rel_5a. В результате линкер перестал ругаться, что встретил два определения функции и нормально подменил библиотечную функцию.

Изменено пользователем Alexey75

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что производители компиляторов уже начали писать библиотечные хидеры без extern "С" :)?

Хотя конечно если не включить готовый хидер и наплевать на вопли об отсутствии прототипа, то добиться вышеописанного можно :(

В некоторых случаях совсем необязательно включать хидер, ибо определение функции является и объявлением. Например я постоянно использую свое определение extern "C" __low_level_init(), но при этом никакой дополнительный хидер в main.cpp не включаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Например я постоянно использую свое определение extern "C" __low_level_init(), но при этом никакой дополнительный хидер в main.cpp не включаю.

__low_level_init() не есть библиотечная функция а просто IARовский прибамбас, посему вполне логично

для него отсутствует прототип в библиотечных хидерах и IAR выдает просто болванку в которой все в одном флаконе с хидером. Описывать-же "свои" прототипы для стандартных библиотечных функций есть безобразие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...