gpt4 book ai didi

c++ - 实现一个类想要模拟 std::string 但在将其 push_back 到 vector 时卡住

转载 作者:行者123 更新时间:2023-11-28 04:07:48 29 4
gpt4 key购买 nike

我已经实现了一个 String 类。当我将 String 对象 push_back 到 Vector 时,程序卡住了。如果您有兴趣,请帮我审核一下。

字符串.h

#pragma once
#include <iostream>
#include <memory>
#include <string>

class String {
public:
String();
String(const char *);
String(const String &);
String(const std::string &);
String(String &&) noexcept;
String &operator=(String &&) noexcept;
~String();
String &operator=(const String &);
std::string to_string() const;

friend std::ostream &operator<<(std::ostream &os, String s);

private:
std::pair<char *, char *>
alloc_n_copy(char *, char *);
void free();
static std::allocator<char> alloc;
char *beg;
char *end;
size_t length;
};

字符串.cpp

#include "stdafx.h"
#include <cstring>
#include "String.h"

std::allocator<char> String::alloc = std::allocator<char>();

String::String()
: beg(nullptr), end(nullptr), length(0) {}

String::String(const char *ptr) {
std::cout << "Const char constructor execute" << std::endl;
const char *tmp = ptr;
while (*tmp++ != '\0') ++length;
beg = alloc.allocate(length);
end = std::uninitialized_copy(ptr, tmp, beg);
}

String::String(const std::string &s) {
std::cout << "Const string constructor execute" << std::endl;
strcpy_s(beg, s.size(), s.c_str());
length = s.size();
char *tmp = beg;
end = tmp + length;
}

String::String(const String &s) {
std::cout << "Copy constructor execute" << std::endl;
beg = alloc.allocate(s.length);
end = std::uninitialized_copy(s.beg, s.end, beg);
}

std::pair<char *, char *>
String::alloc_n_copy(char *beg, char *end) {
auto newBeg = alloc.allocate(end - beg);
return{ newBeg, std::uninitialized_copy(beg, end, newBeg) };
}

String &String::operator=(const String &s) {
length = s.length;
auto newStr = alloc_n_copy(s.beg, s.end);
free();
beg = newStr.first;
end = newStr.second;
return *this;
}

String::String(String &&s) noexcept : beg(s.beg), end(s.end), length(s.length) {
std::cout << "Move constructor execute" << std::endl;
s.beg = s.end = nullptr;
s.length = 0;
}

String &String::operator=(String &&s) noexcept {
if (this != &s) {
beg = s.beg;
end = s.end;
length = s.length;
s.beg = s.end = nullptr;
s.length = 0;
}
return *this;
}

void String::free() {
while (length-- >= 0) {
alloc.destroy(end--);
}
alloc.deallocate(beg, length);
}

String::~String() {
free();
}

std::string String::to_string() const {
std::string s(beg);
return s;
}

std::ostream &operator<<(std::ostream &os, String s) {
std::string str(s.beg);
os << str;
return os;
}

主要.cpp

int main()
{
vector<String> v;
String s1("abc");
String s2("def");

v.push_back(s1);
v.push_back(s2);

return 0;
}

结果:

Const char constructor execute
Const char constructor execute
Copy constructor execute
Move constructor execute

我不知道为什么第二个 push_back 是 move 结构。

并且当 push_back 完成时,程序无法退出。是否有资源释放失败?

谢谢

最佳答案

你的程序阻塞的原因是因为你的析构函数永远不会终止:

void String::free() {
while (length-- >= 0) {
alloc.destroy(--end);
}
alloc.deallocate(beg, length);
}

由于 length 是无符号类型,因此 length >= 0 始终为真。您可能不想在此处将 length 递减,然后再将其用作 alloc.deallocate() 的参数。我建议:

void String::free() {
while (end > beg) {
alloc.destroy(end--);
}
alloc.deallocate(beg, length);
}

还有其他错误,例如在 char const* 构造函数中使用它之前未能初始化 length (我不明白你为什么不直接使用std::strlen()) 并且在 std::string 构造函数中分配失败。我建议使用一组好的警告(我使用了 g++ -std=c++2a -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds -Weffc++)并解决它们全部。通过这种方式很容易识别出上述问题。

编译清除警告后,然后在 Valgrind 或其他内存检查器下运行您的代码以了解一些 Unresolved 问题。

关于c++ - 实现一个类想要模拟 std::string 但在将其 push_back 到 vector 时卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58394709/

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