#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
это правильный выбор здесь.