Должна ли память структуры взаимодействия освобождаться после вызова? - PullRequest
2 голосов
/ 06 декабря 2010

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

extern "C" __declspec(dllexport) typedef struct
{
    int num_vertices;
    int *vertices;

} Vertex_List;

extern "C" __declspec(dllexport) typedef struct
{
    int num_cycles;
    Vertex_List *cycles;
} Cycle_List;

extern "C" __declspec(dllexport) typedef struct
{
    int v1;
    int v2;

} Edge;

extern "C" __declspec(dllexport) typedef struct
{
    int num_edges;
    Edge *edgeList;
} Edge_List;

extern "C" __declspec(dllexport) Cycle_List Traversal(Edge_List edgeList);

И это мой соответствующий код структуры .Net:

[StructLayout(LayoutKind.Sequential)]
internal struct EdgeSpecial
{
    public int v1;
    public int v2;
}

[StructLayout(LayoutKind.Sequential)]
internal struct Edge_List                 
{
    public int num_edges; 
    public IntPtr edgeList;
}

[StructLayout(LayoutKind.Sequential)]
internal  struct  Vertex_List
{
    public int num_vertices;
    public IntPtr vertices;
}

[StructLayout(LayoutKind.Sequential)]
internal  struct Cycle_List
{
    public int num_cycles;
    public IntPtr cycles;
}

[DllImport("BoostAPI.dll")]
public static extern Cycle_List Traversal([In] Edge_List edgeList);

Вот какЯ делаю мой вызов в .Net функции:

//converts from my edge structure to the interop structure
Edge_List edgeList = EdgeConvertor(edges); 

//interop call
Cycle_List cycleInterop = GraphBoostInterop.Traversal(edgeList);              

// converts from interop cycle structure to my .NET structure
var cycleList = CycleListConvertor(cycleInterop);   

Проблема в том, что после преобразования cycleInterop в мою структуру данных cycleList есть ли необходимость в освобождении edgeList и cycleInterop?Должен ли я создать FreeCycle или такой код внутри C ++, а затем передать в него структуру для освобождения памяти?Если да, то как?

Редактировать: Вот как Cycle_List заполняется в C ++;в основном я просто копирую информацию из аналогичной структуры данных (используя std::vector к ней).

  i=0;
    Cycle_List cList;
    cList.num_cycles=cycleList.CycleList.size();
        cList.cycles=(Vertex_List*)malloc(cList.num_cycles*sizeof(Vertex_List));
    for(std::vector<Cycle>::const_iterator it = cycleList.CycleList.begin(); it !=  cycleList.CycleList.end(); ++it)
  {


      Cycle cycle = *it;
      Vertex_List vList;
      vList.num_vertices = cycle.VertexList.size();
          vList.vertices= (int*) malloc ( vList.num_vertices*sizeof(int));
      j=0;
      for(std::vector<int>::const_iterator intList=cycle.VertexList.begin(); intList!=cycle.VertexList.end(); ++intList)
      {
          vList.vertices[j++] = *intList;    

      }

      cList.cycles[i++]=vList;



  }

Ответы [ 2 ]

1 голос
/ 06 декабря 2010

Поскольку вы заполняете структуру Cycle_List внутри своего собственного кода C ++, вы должны написать вторую функцию C ++, которая освобождает структуру Cycle_List.

Поскольку вы используете malloc для инициализацииCycle_List::cycles и Vertex_List::vertices члены, вы должны использовать free для их очистки.

Как говорит @Aliostad, "ответственность за освобождение лежит на том, кто выделил память".

1 голос
/ 06 декабря 2010

Ответственность за освобождение несет тот, кто выделил память. Как бы просто это ни звучало, это золотое правило.

Согласно этому правилу, когда неуправляемая DLL возвращает мне указатель на неуправляемую структуру, это означает, что он выделил память. Поэтому освобождение памяти потребует вызова неуправляемой DLL, чтобы освободить ее, когда вы закончите - что, по-видимому, происходит в тот момент, когда вы завершаете преобразование неуправляемого указателя в управляемую структуру.

Я не знаком с вашей неуправляемой библиотекой, но я использовал OpenCV, и у нее есть cvRelease(**ptr), которая освобождает память и сбрасывает указатель на ноль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...