Использование оператора new в смешанном коде c и c ++ - PullRequest
1 голос
/ 12 июня 2019

Рассмотрим программу со смешанным кодом C и C ++.Часть C ++ содержит класс, который динамически выделяет стиль C typedef struct.Минимальный пример:

obj.h (код C)

typedef struct _Ctype {
  int i;
} Ctype;

class.hpp (код C ++)

struct A {
  struct _Ctype *x;
  A(int i);
  ~A();
};

class.cpp (код C ++)

#include "class.hpp"

extern "C" {
#include "obj.h"
}


A::A(int i)
{
  x = new struct _Ctype;
  x->i = i;
}

A::~A()
{
  delete(x);
}

main.cpp (код C ++, основная программа)

#include "class.hpp"

int main()
{
  A a(3);
  return 0;
}

(Обоснование для этого дизайна исходит из этого ответа )

Безопасно ли (то есть, нет UB) использовать выражение new для выделения типа стиля C struct _Ctype, как в приведенном выше коде, или лучше использовать C-стиль malloc / free?

class.cpp (код C ++, альтернатива)

#include <cstdlib>
#include "class.hpp"

extern "C" {
  #include "obj.h"
  }


A::A(int i)
{
  x = (struct _Ctype *)malloc(sizeof(struct _Ctype));
  x->i = i;
}

A::~A()
{
  free(x);
}

ADDITION

Чтобы прояснить вопрос после некоторых комментариев ниже: В приведенном ниже минимальном примере весь код компилируется с помощью компилятора C ++.Однако можно подумать об использовании кода C ++ вместе с библиотекой C.Затем вопрос можно переформулировать следующим образом:

  • Если я выделю память для стиля C typedef struct с помощью кода C ++, сможет ли библиотека C безопасно использовать выделенную переменную?Если да, безопасны ли оба приведенных выше варианта?

Обратите внимание, что можно также подумать о выделении памяти для Ctype через функцию C, чтобы код C ++ управлял только указателем на нее.Например:

obj.h (C-код)

typedef struct _Ctype {
  int i;
} Ctype;

Ctype *allocate_Ctype();
void deallocate_Ctype(Ctype* p);

obj.C (C-код)

#include <stdlib.h>
#include "obj.h"

Ctype *allocate_Ctype()
{
   return (Ctype *)malloc(sizeof(Ctype));
}

void deallocate_Ctype(Ctype *p)
{
   free(p);
}

class.cpp (код C ++)

#include "class.hpp"

extern "C" {
#include "obj.h"
}


A::A(int i)
{
  x = allocate_Ctype();
  x->i = i;
}

A::~A()
{
  deallocate_Ctype(x);
}

(Примечание: конечно, необходимо правильно определить конструктор копирования и назначение оператора класса A, кодслужит иллюстрацией вопроса)

1 Ответ

4 голосов
/ 12 июня 2019

Пока освобождение происходит только под вашим контролем и с использованием выражения delete, проблем вообще не возникает. Код C, взаимодействующий со структурой, не заботится о том, как она была выделена.

Примечание: имя _Ctype недопустимо в C ++, так как начинается с подчеркивания, за которым следует заглавная буква. Такие имена (а также имена, содержащие двойное подчеркивание) зарезервированы для компилятора и стандартной библиотеки.

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