2016-07-14 4 views
-4

Я написал некоторый массив, который выделяет память, и каждое значение в массиве является типом. Затем у меня есть другой массив, который состоит из первого массива для ссылок.Realloc создает висячие указатели?

Оба массива могут расти. Он использует realloc. Поскольку второй массив содержит указатели в первом, они, разумеется, не обновляются, когда изменяется первый массив (я не делаю это вручную, и нет GC). Разумеется, все указатели во втором массиве недействительны! (они указывают на память, свободную от realloc).

  1. Это верно?

  2. Похоже, что это сделает упорные указатели на блоки памяти, которые могут перемещаться очень опасно?

  3. Какое стандартное решение? Не использовать «глобальные» указатели? Использование указателей для указателей на указатели? Я думаю, что я мог бы использовать 2-й массив ** и мог бы, вероятно, заставить все работать.

  4. В условиях МТ все еще хуже. Доступ к локальным указателям может быть перемещен посередине, затем память изменилась, а локальный указатель теперь ошибочен. (Который, конечно, может быть разрешен путем предотвращения ходов блокировкой и т. Д.)

  5. Идите с функциональным программированием?

+1

1. Я думаю, что у вас есть проблема с структурой данных. 2. Почему вы используете указатели? Разумные указатели. –

+3

Не храните указатели на первый массив. Храните индексы. Они останутся действительными, если ваш первый массив будет продолжать расти. – PSkocik

+0

@PSkocik Да, но это не всегда решение. Это работает в этом случае, потому что я использую индексный массив. Он не отвечает на вопрос, только пытается предоставить конкретное решение (решение, которое я уже слышал, и когда я впервые написал код, который был моим первоначальным ответом .. Но я был как «Привет, int и void * занимает То же место, почему бы просто не использовать указатель! »... затем быстро понял, что это была плохая идея. – AbstractDissonance

ответ

2

Да, realloc может аннулировать ваши ссылки. Если нет непрерывного пространства для перемещения, ваш массив будет перемещен. Рассмотрите возможность использования контейнера в качестве std :: deque.

+0

Только для записи стандартные ссылки на контейнеры (т. итераторы) также будут аннулированы с использованием операций, которые изменяют размер контейнеров. –

+0

Для std :: vector и некоторых других контейнеров, которые являются истинными. Но std :: deque просто отменяет ссылки для линейной вставки. push_back и push_front не аннулируют его итераторы. См .: http://en.cppreference.com/w/cpp/container/deque – rflobao

1

1) Это верно?

Да.

2) Похоже, что это сделает упорные указатели на блоки памяти, которые могут перемещаться очень опасно?

Да.

3) Какое стандартное решение?

Вы разрабатываете приложение таким образом, чтобы срок жизни ваших объектов был четко определен, чтобы вы не ссылались на них после того, как они больше не требуются.

4) В среде МТ все еще хуже. Доступ к локальным указателям может быть перемещен посередине, затем память изменилась, а локальный указатель теперь ошибочен. (Который, конечно, может быть разрешен путем предотвращения перемещений блокировкой и т. Д.)

Очевидно, вы никогда не должны использовать указатель, который больше не указывает на его ресурс. Управление общими ресурсами в среде МТ является нетривиальным, и для его реализации существует целая куча инструментов и методов.

5) Идите с функциональным программированием?

Всегда желательно избегать указателей, если можете.

Без особых проблем трудно дать конкретное решение. Но для того, чтобы «не указывать на исчезнувшие ресурсы», у нас есть различные инструменты для использования. У нас есть умные указатели, у нас есть контейнеры и у нас есть значение семантика. Нам нужно понять, как использовать все те, но также нам нужно дизайн с объектом срок службы в виду как майор рассмотрение.

Срок службы объекта должен быть всегда быть важным фактором. Однако некоторые языки (например, Java, например) смягчают негативный дизайн, предоставляя «более безопасную» среду. C++, с другой стороны, довольно менее прощает. Однако у него есть целая куча сложных инструментов для этой задачи. Это означает более крутую кривую обучения, но большую эффективность и лучший контроль.

Смежные вопросы