Повреждение кучи Обнаружено в проблеме с алмазами

#c #oop #diamond-problem

#c #ООП #алмаз-проблема

Вопрос:

Я использую виртуальное наследование для решения проблемы с алмазами. Код завершает работу после вызова деструктора базового класса A с ошибкой «Обнаружено повреждение кучи» .:

 #include lt;cstringgt; class A {  char* name; public:  A(const char* name)  {  int len = strlen(name)   1;  this-gt;name = new char[len];  strncpy(this-gt;name, name, len)[len] = '';  }  virtual ~A()  {  delete[] this-gt;name;  } };  class B : virtual public A { public:  B(const char* name) : A(name) {}  virtual ~B() {} }; class C : virtual public A { public:  C(const char* name) : A(name) {}  virtual ~C() {} };  class D : public B, public C { public:  D(const char* name) : A(name), B(name), C(name) {}  virtual ~D() {} };  int main() {  D d("qwerty");  }  

Есть какие-нибудь идеи?

Комментарии:

1. Вы знаете , что this-gt;name это достаточно большой размер для целевой строки, потому что вы выделили для нее место. Нет необходимости снова проверять длину strncpy (что в любом случае сложно исправить, как показывает повреждение кучи). Просто используй strcpy .

Ответ №1:

Изменить:

 strncpy(this-gt;name, name, len)[len] = '';  

Для:

 strncpy(this-gt;name, name, len);  

Вы [len] обращаетесь к одному из них после конца вашего массива и strncpy уже копируете завершающий '' .

Комментарии:

1. Большое вам спасибо!

2. strncpy не записывает терминатор nul, если исходная строка длиннее len . Поскольку известно, что целевой массив достаточно велик, нет необходимости проверять длину. strcpy это правильный выбор здесь.