gpt4 book ai didi

c++ - 为什么我的删除功能总是出现段错误

转载 作者:太空宇宙 更新时间:2023-11-04 12:31:11 25 4
gpt4 key购买 nike

我有一个任务,我需要使用重载的析构函数来删除动态分配的指针。但是,当它运行时,我的一些指针会被删除,直到出现段错误,其中一个对象的指针指向“和第二个”,这是使用参数化构造函数创建的。我试图通过并确保删除运算符有括号(因为我的新运算符有)我通过打印出它的信息和地址来确保该对象仍然存在。我试图重写我的分配函数,并且我试图检查我的析构函数以查看它在哪里搞砸了。如果有帮助,我已经包括了我的析构函数、我的分配函数、我的释放函数和我的参数化构造函数。

'''
//Destructor
MyString::~MyString()
{
buffer_deallocate();
};

void MyString::buffer_deallocate() {
cout << m_buffer << endl;
delete[](m_buffer);
m_buffer = NULL;
m_size = 0;

}

void MyString::buffer_allocate(size_t size) {
try {

m_buffer = new char[size];
m_size = size;
}
catch(bad_alloc&)
{
cout << "Errror: Unable to allocate memory" << endl;
buffer_deallocate();
}

}


//Parameterized Constructor
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];
}

};
'''

然而,每次我在“和第二个”之后得到的输出是段错误(核心转储)

编辑:我已经尝试了大部分推荐的方法。至少据我所知,问题仍然存在,我现在意识到我的代码有点稀疏。 (请原谅我,我还在学习。)下面是新代码以及函数文件的其余部分以供引用:

'''
#include<iostream>
#include<string.h>
using namespace std;

#include"MyString.h"


//Default Constructor
MyString::MyString()
:m_size(0), m_buffer(NULL)
{
buffer_allocate(0);
};



//Parameterized Constructor
MyString::MyString(const char * str)
:m_size(strlen(str)+1), m_buffer(NULL)
{
buffer_allocate(m_size);
strncpy(m_buffer, str, m_size);

};



//Copy Constructor
MyString::MyString(const MyString & other)
:m_size(0), m_buffer(NULL)
{
const char * otherPtr = other.c_str();
buffer_allocate(other.size());

for(int i = 0; i < size(); i++)
{
m_buffer[i] = otherPtr[i];
}
m_buffer[m_size] = '\0';
};


//Destructor
MyString::~MyString()
{
buffer_deallocate();
};



size_t MyString::size() const
{
return m_size;
}



size_t MyString::length() const{
return m_size-1;
}



const char * MyString::c_str() const{
return m_buffer;
}


bool MyString::operator==(const MyString & other) const {
char * m_bufferPointer = m_buffer;
while(*m_bufferPointer++)
{
const char * str_ptr = other.c_str();
if(*m_buffer != *str_ptr++)
{
return 0;
}
}
return 1;
}


MyString & MyString::operator=(const MyString & rhs) {
buffer_deallocate();

buffer_allocate(rhs.size());
const char * c_strPtr = rhs.c_str();
int i;
for(i = 0; i < rhs.size(); i++)
{
this->m_buffer[i] = c_strPtr[i];
}
return *this;
}




MyString MyString::operator+ (const MyString & other_myStr) const {

char * temp_pointer;
temp_pointer;
size_t temp_size = m_size + other_myStr.size();
//New Combined Buffer for Concatanation
try {
temp_pointer = new char[temp_size];
temp_pointer = strcat(this->m_buffer, other_myStr.c_str());

}
catch(bad_alloc&)
{
cout << "Error: Unable to Allocate Memory";
return NULL;
}
return MyString(temp_pointer);
}



char & MyString:: operator[](size_t index) {
return m_buffer[index];
}


const char & MyString::operator[] (size_t index) const {
return m_buffer[index];
}


ostream & operator << (ostream& os, const MyString & myStr) {
os << myStr.m_buffer;
return os;

}

void MyString::buffer_deallocate() {



cout << "Trying to delete : " <<m_buffer << endl;
if(m_buffer){
delete[](m_buffer);
}
cout << " Success" <<endl;
m_buffer = NULL;
m_size = 0;

}

void MyString::buffer_allocate(size_t size) {
try {

m_buffer = new char[size];
m_size = size;
}
catch(bad_alloc&)
{
cout << "Errror: Unable to allocate memory" << endl;
m_size = 0;
}

}

'''

最佳答案

MyString::buffer_deallocate

cout << m_buffer << endl;

要求 m_buffer 以 null 结尾。不幸的是,MyString::MyString(const char * str) 不提供此保证。

你可以

for(int i = 0; i < m_size; i++)
{
cout << m_buffer[i] << endl;
}

改为逐字符打印字符串,但浪费一个字节、null 终止并利用标准库可能更有用

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);
}

附录:

你的类可能违反了the Rule of Three .如果 MyString 没有复制构造函数和赋值运算符来配合析构函数,任何复制,无论是有意还是无意,都会将 MyString 变成定时炸弹。其中一个拷贝的析构函数将在其他拷贝之前运行,从而使其他拷贝没有有效的 m_buffer

MyString::buffer_allocate 不能安全地返回 void 除非它允许异常传播。捕获 bad_alloc 会使对象在 m_buffer 中没有有效分配,程序的其余部分将不知道这一点。程序中的所有其他访问都必须测试有效缓冲区或参与尝试访问无效内存的未定义行为。让异常失败并被更适合决定要做什么的程序的另一部分捕获可能更好。

MyString::buffer_allocate 如果在 MyString 上调用时将泄漏现有分配,而该分配已在 m_buffer 中有效分配。我推荐一个

if (m_buffer) 
{
delete[] m_buffer;
}

并在MyString的构造函数中将m_buffer初始化为null

MyString(const char* str)
: m_size(std::strlen(str)), m_buffer(nullptr)
{
buffer_allocate(m_size);
std::strncpy(m_buffer, str, m_size);
}

关于c++ - 为什么我的删除功能总是出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58613505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com