Выделение кучи для std::array

Согласно этот вопрос std::array выделяется в стеке. Однако при использовании его вместе с Valgrind он показывает мне выделение кучи, даже для элементов, которые выделены в стеке. Это ложное срабатывание или правда?

Здесь следуют два mwe, чтобы проиллюстрировать поведение.

Нет кучи:

Следующий код:

#include <array>

int main() {
    std::array<int*, 1> map;
    int value = 0;
}

Производит ожидаемый следующий вывод Valgrind:

==14425== HEAP SUMMARY:
==14425==     in use at exit: 0 bytes in 0 blocks
==14425==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated

С кучей:

Однако, если я попробую этот код:

#include <array>

int main() {
    std::array<int*, 1> map;
    int value = 0;

    map.at(0) = &value;
}

Valgrind дает мне

==14539== HEAP SUMMARY:
==14539==     in use at exit: 72,704 bytes in 1 blocks
==14539==   total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==14539== 
==14539== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==14539==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14539==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==14539==    by 0x40106B9: call_init.part.0 (dl-init.c:72)
==14539==    by 0x40107CA: call_init (dl-init.c:30)
==14539==    by 0x40107CA: _dl_init (dl-init.c:120)
==14539==    by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==14539== 

Добавлены настройки компиляции:

g++ -std=c++11 -O0 valgrind.cpp -o valgrind_build -I ../fake -I ../src
valgrind --track-origins=yes --dsymutil=yes --leak-check=full --show-leak-kinds=all ./valgrind_build

valgrind --version
valgrind-3.11.0

g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

person magu_    schedule 13.02.2019    source источник
comment
Какой компилятор и какие флаги? Всё это в любом случае должно быть убрано в оптимизированной сборке.   -  person Matthieu Brucher    schedule 13.02.2019
comment
может быть ложным срабатыванием, трудно придумать использование этого фрагмента, которое не оставит вас с оборванным указателем в массиве (или с использованием распределения кучи)   -  person 463035818_is_not_a_number    schedule 13.02.2019
comment
В соответствии с этим вопросом std::array размещается в стеке. Нет, это не то, о чем здесь говорится. В нем говорится, что std::array не разрешено выполнять выделение кучи. Если вы выделите array себя в куче, то и массив будет в куче.   -  person Nicol Bolas    schedule 13.02.2019
comment
Ваш второй пример выглядит так же, как глобальный объект в стандартной библиотеке (например, cin и cout).   -  person NathanOliver    schedule 13.02.2019
comment
очень связано: stackoverflow.com/questions/31775034/   -  person NathanOliver    schedule 13.02.2019


Ответы (1)


Код

map.at(0) = &value;

вводит проверку границ, которая, в свою очередь, может потребовать использования материала, выделенного динамически (например, из библиотеки <iostream>).

Вы можете попробовать еще раз с

map[0] = &value;

который не применяет связанные проверки.

person πάντα ῥεῖ    schedule 13.02.2019
comment
Ничего себе, не думал о проверке привязки, вводящей динамическое распределение. Но вы правы. - person magu_; 13.02.2019
comment
Еще одна причина не использовать at() автоматически. - person Pete Becker; 13.02.2019
comment
Единственная динамически выделяемая память, которую я мог видеть at(), использовалась при создании исключения std::out_of_range. Если вы не выходите за пределы, исключение не выдается. Итак, что еще может использовать динамическое размещение в этом случае? Может быть, какая-то статическая инициализация, даже если исключение не выбрасывается? - person Remy Lebeau; 13.02.2019
comment
@remy Может быть, какая-то статическая инициализация, даже если исключение не выбрасывается? Конечно, я об этом и думал. - person πάντα ῥεῖ; 13.02.2019