in MyString::buffer_deallocate
cout << m_buffer << endl;
требует, чтобы m_buffer
был нулевым. К сожалению, MyString::MyString(const char * str)
не дает такой гарантии.
Вы можете
for(int i = 0; i < m_size; i++)
{
cout << m_buffer[i] << endl;
}
вместо того, чтобы печатать строку символ за символом, но, вероятно, более полезно тратить байт, нульзавершите работу и воспользуйтесь стандартной библиотекой
MyString::MyString(const char * str)
:m_size(0)
{
const char * strPtr = str;
while(*strPtr)
{
strPtr++;
m_size++;
}
buffer_allocate(m_size);
for(int i = 0; i < m_size; i++)
{
m_buffer[i] = str[i];
}
m_buffer[m_size] = '\0'; // add the null
}
, а затем
void MyString::buffer_allocate(size_t size) {
try {
m_buffer = new char[size+1]; // +1 for the null terminator
m_size = size;
}
catch(bad_alloc&) // this is a bad thing to do here. More on that later.
{
cout << "Errror: Unable to allocate memory" << endl;
buffer_deallocate();
}
}
Но мы можем упростить это с помощью нескольких вызовов библиотечных функций.
MyString::MyString(const char * str)
:m_size(strlen(str))
{
buffer_allocate(m_size);
strcpy(m_buffer, str);
}
Приложение:
Ваш класс может нарушать Правило трех . Если у MyString
нет конструктора копий и оператор присваивания, чтобы идти вместе с деструктором, любые копии, намеренные или случайные, превратят MyString
в бомбу замедленного действия. Деструктор одной из копий будет запущен до того, как остальные оставят остальные без действительного m_buffer
.
MyString::buffer_allocate
, не сможет безопасно вернуть void
, если не разрешит распространение исключения. Поймав bad_alloc
, вы оставите объект без действительного выделения на m_buffer
, и остальная программа не узнает об этом. Любой другой доступ в программе должен проверять допустимый буфер или участвовать в неопределенном поведении, пытаясь получить доступ к недействительной памяти. Вероятно, лучше позволить исключению провалиться и быть пойманным другой частью программы, которая лучше подходит для принятия решения о том, что делать.
MyString::buffer_allocate
приведет к утечке существующего выделения при вызове на MyString
, который уже имеет действительное распределение на m_buffer
. Я рекомендую
if (m_buffer)
{
delete[] m_buffer;
}
и инициализировать m_buffer
в null в конструкторе MyString
MyString(const char* str)
: m_size(std::strlen(str)), m_buffer(nullptr)
{
buffer_allocate(m_size);
std::strncpy(m_buffer, str, m_size);
}