Сбой Calloc на устройстве ARM

У меня есть программа на C++, которая использует общую библиотеку C (а именно Darknet) для загрузки и использования облегченных нейронных сетей. .

Программа безупречно работает под Ubuntu Trusty на x86_64, но вылетает из-за ошибки сегментации под той же ОС, но на устройстве ARM. Причина сбоя в том, что calloc возвращает NULL при выделении памяти для массива. Код выглядит следующим образом:

l.filters = calloc(c * n * size * size, sizeof(float));
...
for (i = 0; i < c * n * size * size; ++i)
    l.filters[i] = scale * rand_uniform(-1, 1);

Итак, после попытки записи первого элемента приложение останавливается с segfault.

В моем случае объем выделяемой памяти составляет 4,7 МБ, а доступно более 1 ГБ. Я также пытался запустить его после перезагрузки, чтобы исключить фрагментацию кучи, но с тем же результатом.

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

Valgrind не сообщает мне ничего нового:

==2591== Invalid write of size 4
==2591==    at 0x40C70: make_convolutional_layer (convolutional_layer.c:135)
==2591==    by 0x2C0DF: parse_convolutional (parser.c:159)
==2591==    by 0x2D7EB: parse_network_cfg (parser.c:493)
==2591==    by 0xBE4D: main (annotation.cpp:58)
==2591==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2591==
==2591==
==2591== Process terminating with default action of signal 11 (SIGSEGV)
==2591==  Access not within mapped region at address 0x0
==2591==    at 0x40C70: make_convolutional_layer (convolutional_layer.c:135)
==2591==    by 0x2C0DF: parse_convolutional (parser.c:159)
==2591==    by 0x2D7EB: parse_network_cfg (parser.c:493)
==2591==    by 0xBE4D: main (annotation.cpp:58)
==2591==  If you believe this happened as a result of a stack
==2591==  overflow in your program's main thread (unlikely but
==2591==  possible), you can try to increase the size of the
==2591==  main thread stack using the --main-stacksize= flag.
==2591==  The main thread stack size used in this run was 4294967295.
==2591==
==2591== HEAP SUMMARY:
==2591==     in use at exit: 1,731,358,649 bytes in 2,164 blocks
==2591==   total heap usage: 12,981 allocs, 10,817 frees, 9,996,704,911 bytes allocated
==2591==
==2591== LEAK SUMMARY:
==2591==    definitely lost: 16,645 bytes in 21 blocks
==2591==    indirectly lost: 529,234 bytes in 236 blocks
==2591==      possibly lost: 1,729,206,304 bytes in 232 blocks
==2591==    still reachable: 1,606,466 bytes in 1,675 blocks
==2591==         suppressed: 0 bytes in 0 blocks
==2591== Rerun with --leak-check=full to see details of leaked memory
==2591==
==2591== For counts of detected and suppressed errors, rerun with: -v
==2591== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 402 from 8)
Killed

Я действительно запутался, что может быть причиной. Кто-нибудь может мне помочь?


person Dmytro Prylipko    schedule 07.04.2016    source источник
comment
Каковы значения c, n и size? Какой тип i?   -  person Eugene Sh.    schedule 07.04.2016
comment
А как же in use at exit: 1,731,358,649 bytes in 2,164 blocks?   -  person LogicStuff    schedule 07.04.2016
comment
Возможно, у вас есть утечки памяти, вызывающие сбой распределения? valgrind показывает много выделенной, но не освобожденной памяти. Выведите errno, если выделение не удалось.   -  person kaylum    schedule 07.04.2016
comment
Я не читал все это, но, возможно, здесь есть некоторые подсказки: x86" title="по-разному ли linux malloc ведет себя на руке по сравнению с x86"> stackoverflow.com/questions/19868584/   -  person yano    schedule 08.04.2016
comment
Является ли проблема специфичной для calloc() или она также возникает, если вы заменяете вызов calloc() функцией, которая вызывает malloc(), а затем вручную очищает буфер памяти перед его возвратом? (на самом деле это звучит так, как будто ваша куча каким-то образом повреждена)   -  person Jeremy Friesner    schedule 08.04.2016
comment
Учитывая этот размер кучи, я предполагаю, что ему просто не хватило места для расширения (между другими вещами, разбросанными по адресному пространству) - действительно ли то же самое работает безупречно на x86, или это просто 64-битный адрес пространство дает ему достаточно места для веселой утечки, пока выполнение не завершится?   -  person Notlikethat    schedule 08.04.2016