这里是程序
using namespace std;
template <typename T>
class Test
{
public:
struct Node{
T data;
Node *next;
};
void setData(T data)
{
head = reinterpret_cast<Node*>(storage);
head->data = data;
}
private:
unsigned char storage[2048];
Node* head;
};
int main()
{
Test<std::string> test;
test.setData("Hello");
return 0;
}
上面的程序可以编译,并且当参数为int类型时也可以正常工作。但是当我将参数设置为std :: string时,它崩溃了-head-> data = data;
是我必须明确处理std :: string的事情。
提前感谢。
您对未初始化的内存进行操作。尤其是您尝试实现自己的内存管理,这将在99%的实现中失败。
您可以在创建的类中简单地使用new
和delete
,而不再担心内存。
#include <string>
template <typename T>
struct Node {
T data;
Node *next;
};
template <typename T>
class Test
{
public:
Test() {
head = new Node<T>();
}
~Test() {
delete head; head = nullptr;
}
void setData(T data) {
if (head = nullptr) {
head->data = data;
}
}
private:
Node<T>* head = nullptr;
};
int main() {
Test<std::string> test_string;
Test<int> test_int;
test_string.setData("Hello");
test_int.setData(1);
return 0;
}
重要注意事项:
Test
的构造函数中,将分配内存new
,必须有一个delete
。所以请注意析构函数nullptr
using namespace std;
。如果这样做,您会open
很大的名称空间,该名称空间可能会与您的某些类名或函数名冲突。此错误几乎找不到。免责声明:这适用于MSVC2017。
Bonus
对于更现代的c++
,可以使用std::unique_ptr
。
#include <string>
#include <memory>
template <typename T>
struct Node {
T data;
Node *next;
};
template <typename T>
class Test
{
public:
void setData(T data)
{
if (head = nullptr)
{
head->data = data;
}
}
private:
std::unique_ptr<Node<T>> head = std::make_unique<Node<T>>();
};
int main()
{
Test<std::string> test_string;
Test<int> test_int;
test_string.setData("Hello");
test_int.setData(1);
return 0;
}
您告诉编译器将数组storage
视为Node
结构。但是storage
中的数据未进行任何初始化,其内容为indeterminate,并且以任何方式使用它会导致undefined behavior。
更具体地说,“结构”的成员未构造或初始化,因此尝试将成员data
用于任何复杂的事情(如您的情况)很可能导致崩溃。
简单的解决方案是使用placement new
head = new (storage) Node;
请注意,在放置new
后您不能delete
该对象,您需要显式调用析构函数
head->~Node();