我不是C ++非用户,我只是在尝试一些有趣的事情,被卡住了,我想我做错了。
我有我自己的类的std::map
(std::map<MyClass*, MyClass*>
),我试图过滤出一个子集,将其存储为临时(本地实例)std::map<MyClass*, MyClass*>
。问题是,当临时映射超出范围时,将调用MyClass
上的析构函数,并将这些项释放。
我在做什么错?
编辑:同时添加了Dictionary
和MyString
类:
#include <iostream>
#include "Dictionary.h"
Dictionary::Dictionary(const char *filename) {
entries = new std::map<MyString *, MyString *>();
load(filename);
}
void Dictionary::load(const char *filename) {
FILE *fh = fopen(filename, "r");
if (!fh) {
printf("Unable to open file: %s\n", filename);
return;
}
size_t len;
while (!feof(fh)) {
char *line = fgetln(fh, &len);
if (len > 60) {
printf("Line too long, skipping.\n");
continue;
}
// find ";" character and change it to \0
char *delimiter = strstr(line, ";");
if (delimiter == nullptr) {
printf("Line does not contain delimiter.\n");
continue;
}
// if last character in line is newline, subtract length
if (line[len - 1] == '\n') {
len--;
}
entries->insert(std::pair<MyString *, MyString *>(
new MyString(line, (size_t) (delimiter - line)),
new MyString(delimiter + 1, (size_t) (len - (delimiter - line + 1)))));
}
fclose(fh);
}
void Dictionary::list(ComparisonOperations op, MyString *sub) {
std::map<MyString *, MyString *> results;
for (auto &entry : *entries) {
switch (op) {
case StartingOp:
if (entry.first->beginsWith(*sub)) {
results.insert(entry);
}
break;
case ContainingOp:
if (entry.first->contains(*sub)) {
results.insert(entry);
}
break;
case EndingOp:
if (entry.first->endsWith(*sub)) {
results.insert(entry);
}
break;
}
}
// print results
Dictionary::print(std::cout, results);
}
void Dictionary::print(std::ostream &os, std::map<MyString *, MyString *> &results) {
if (results.empty()) {
os << "No match found." << std::endl;
} else if (results.size() == 1) {
auto result = results.begin();
os << (MyString) *(result->first)
<< " => " << (MyString) *(result->second) << std::endl;
} else {
for (auto &result : results) {
os << (MyString) *(result.first) << std::endl;
}
}
}
---
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include "MyString.h"
MyString::MyString() {
buffer = (char *) malloc(1);
memset(buffer, 0, 1);
}
MyString::MyString(const char *str) {
buffer = (char *) malloc(MAX_MY_STRING_LEN + 1);
memset(buffer, 0, MAX_MY_STRING_LEN + 1);
strncpy(buffer, str, MAX_MY_STRING_LEN);
}
MyString::MyString(const char *str, int len) {
buffer = (char *) malloc(len + 1);
memset(buffer, 0, len + 1);
strncpy(buffer, str, len);
}
MyString::~MyString() {
if (buffer != nullptr) {
printf("dealloc string %s!", buffer);
free(buffer);
}
buffer = nullptr;
}
bool MyString::operator==(const MyString &cmp) const {
return strcmp(buffer, cmp.buffer) == 0;
}
bool MyString::operator<(const MyString &cmp) const {
return strcmp(buffer, cmp.buffer) < 0;
}
bool MyString::beginsWith(const MyString &sub) const {
return strstr(buffer, sub.buffer) == buffer;
}
bool MyString::contains(const MyString &sub) const {
return strstr(buffer, sub.buffer) != nullptr;
}
bool MyString::endsWith(const MyString &sub) const {
char *pos = strstr(buffer, sub.buffer);
return (pos - buffer + strlen(sub.buffer)) == strlen(buffer);
}
void MyString::print() {
printf("%s\n", buffer);
}
std::ostream &operator<<(std::ostream &os, const MyString &str) {
return os << ((const char *) str.buffer);
}
[PS:不,这不是我的学校作业,它实际上是朋友的学校作业,我正在尝试它只是为了好玩,因为,正如您所看到的,我的C ++太生锈了。
由于MyString
没有副本构造函数,(MyString) *(result->first)
中的表达式Dictionary::print
创建了一个临时实例,该临时实例借用了对基础数据的引用,然后过早将其从原始所有者下释放了。