Почему указатель на объект в расширенной разделяемой памяти становится недействительным при изменении области видимости? - PullRequest
0 голосов
/ 29 июня 2018

TL; DR: почему указатель на объект в разделяемой памяти становится недействительным после простого изменения области видимости? Указатель не находится в общей памяти. Почему он стал бы бесполезным?


Допустим, у меня есть простой пользовательский тип данных для примера:

class CustomDataType
{
public:
  short val;
  CustomDataType(short val__) { val = val__; };
  virtual ~CustomDataType() {};
  short square() { return val*val; };
};

У меня есть какая-то функция, создающая экземпляр этого объекта в общей памяти и возвращающая указатель на объект:

CustomDataType* someFunction()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{ open_or_create, "Boost", 1024 };
  CustomDataType *i = managed_shm.construct<CustomDataType>("CustomDataTypeObject")(7);
  std::cout << i->square() << std::endl;
  return i;
}

Мой основной вызывает эту функцию, а затем пытается получить доступ к возвращенному указателю:

void main()
{
  CustomDataType* customData = someFunction();
  std::cout << customData->square() << std::endl; // <------- program crashes
}

Первый вызов метода «квадрат» через указатель внутри функции работает.

Однако второй вызов метода 'square' через указатель в main завершается неудачей.

Почему указатель не переживает изменение области видимости? Я нахожусь в том же процессе, объект все еще находится в памяти.

Указатель становится бесполезным, как только managed_shared_memory выходит из области видимости, даже если он ничего не меняет в памяти?

Что-то мне не хватает, чтобы указатель пережил изменение области видимости?

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

Минимальный, полный и проверяемый пример:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>

using namespace boost::interprocess;

class CustomDataType
{
public:
  short val;
  CustomDataType(short val__) { val = val__; };
  virtual ~CustomDataType() {};
  short square() { return val*val; };
};

CustomDataType* someFunction()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{ open_or_create, "Boost", 1024 };
  CustomDataType *i = managed_shm.construct<CustomDataType>("CustomDataTypeObject")(7);
  std::cout << i->square() << std::endl;
  return i;
}

void main()
{
  CustomDataType* customData = someFunction();
  std::cout << customData->square() << std::endl; // <------- program crashes
}

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

С документация :

Когда объект managed_shared_memory уничтожен, объект общей памяти автоматически не отображается, и все ресурсы освобождаются.

Это означает, что когда managed_shm выходит из области видимости, указатель i, который вы возвращаете, становится висящим.

0 голосов
/ 29 июня 2018

Проблема в том, что когда объект управления общей памятью managed_shm выходит из области видимости, он уничтожается и разделяемая память отсоединяется (поэтому все указатели на него становятся недействительными).

Обычно вы используете глобальные переменные для объектов управления общей памятью, поэтому сопоставления совместно используемой памяти остаются действительными до завершения программы (если явно не уничтожено).

...