gpt4 book ai didi

C++ 程序试图加倍释放自定义对象

转载 作者:行者123 更新时间:2023-11-28 06:30:31 27 4
gpt4 key购买 nike

对于 future 的访问者

原来我的自定义类中没有定义复制赋值运算符,因此编译器默认为“复制对象的指针”行为。

如果你像我一样对什么是复制赋值运算符感到困惑,this resource may help you figure out what a "copy assignment operator" looks like in C++ .

原问题提示如下。 (指向原始源代码的链接将在一个月后过期;抱歉!)


我正在开发一个模拟书店的控制台应用程序,但在执行期间我的程序中不断收到 _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 错误消息。在四处搜索(以及一些令人沮丧的调试)之后,我得出的结论是我的对象的析构函数被调用了两次。我希望下面的代码片段能让我更清楚地理解我的意思。 (单击文件名将打开一个包含相关代码的贴图,以便于阅读/整理。)


bookdata.h

#ifndef BOOKDATA_H
#define BOOKDATA_H

class bookData {
private:
char* bookTitle;
char* isbn;
char* author;
char* publisher;
char* dateAdded;
int qtyOnHand;
double wholesale;
double retail;

public:
bookData();
bookData(char* title, char* isbn, char* author, char* publisher, char* date, int qty, double wholesale, double retail);
bookData(bookData& book); // Meant to be called during memberwise assignment
~bookData();

// Various setter & getter funcs
};

#endif

bookData.cpp

#include "globals.h"
#include "bookData.h"

using namespace std;

// Variables in caps are const ints defined in globals.h

bookData::bookData() {
bookTitle = new char[TITLE_LENGTH];
isbn = new char[ISBN_LENGTH];
author = new char[AUTHOR_LENGTH];
publisher = new char[PUBLISHER_LENGTH];
dateAdded = new char[DATE_LENGTH];
qtyOnHand = 0;
wholesale = 0;
retail = 0;

char emptyTitle[2];
emptyTitle[0] = '\0';
setTitle(emptyTitle);
}

// Other constructors are overloaded version of bookData & copy data;
// See example setter function below destructor

bookData::~bookData() {
if (bookTitle)
delete [] bookTitle;
else
return;
delete [] isbn;
delete [] author;
delete [] publisher;
delete [] dateAdded;
}

// Setter functions are of this form (excl. ints & doubles)
void bookData::setTitle(const char* input) {
for (int len = 0; len < TITLE_LENGTH - 1; len++) {
*(bookTitle + len) = *(input + len);
if (*(input + len) == '\0')
break;
else if (len == TITLE_LENGTH - 2)
*(bookTitle + ++len) = '\0';
}
}

// Getter functions are of this form (excl. ints & doubles)
const char* bookData::getTitle() { return bookTitle; }

reports.cpp (the file that's calling the destructor twice)

void repQty() {

// Again, variables in all caps are defined in globals.h if you don't see
// their declaration
bookData bookArray[MAX_RECORDS];

// Global function which populates bookArray from a datafile
bookData* books = getBooks(bookArray);

// Some code to find the memory address of the first and last book in the records
bookData* HEAD = books;
// Keep advancing until books no longer points to a non-empty bookData object
// "Empty" defined as book's bookTitle variable starting with '\0'
bookData* TAIL = --books;

// Need all 3 pointers for a naive, in place insertion/linear sort routine
// Outputs book data following the sort

// Before returning, calls the destructors for the books in bookArray
// Also calls the destructor for books, HEAD, and TAIL as well
// ...which were already called as part of the bookArray's destructor calls
// Which is where I have my problem now
}

奖金:globals.h

您可能已经注意到,我已经尝试通过在析构函数中使用 if (bookTitle) 来检查 bookData 对象是否已被删除,但是当我通过 VS 的 Step Into 功能运行它时,它仍然评估为真。除了一起对析构函数进行核攻击,我还能做些什么来解决这个问题并在相关对象已经被释放的情况下使析构函数过早退出?

最佳答案

I've already attempted to check whether the bookData object has already been deleted by using if (bookTitle) in the destructor function

由于 delete[] 没有将指针设置为 NULL,因此检查实际上是空操作。

即使您手动将指针设置为 NULL,您也只能解决问题的症状而不是根本原因。

根本原因是您没有实现复制赋值运算符,从而违反了 rule of three .发生的情况是您正在使用隐式生成的复制赋值运算符:

  swap = *books;
*books = *(books - 1);
*(books - 1) = swap;

并且该运算符没有做正确的事情:它复制指针而不是复制数据。双重删除是其直接后果。

此外,复制构造函数的实现可能有问题,但如果不查看其源代码就很难确定。

附言通过使用 std::string 而不是 C 字符串,您会帮自己一个大忙。此外,std::vector 优于 C 数组。

关于C++ 程序试图加倍释放自定义对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27674183/

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