问题描述
下面我有一些用于实现霍夫曼压缩的代码。
我很好奇的是我是否可以在不包含 left
的情况下初始化 right
和 cstdlib
指针,或者更确切地说,我是否可以初始化一个空的内存位置来存储 left
和 right
不使用 malloc。
另外,在我的 combine 函数中,我不想将 "NULL"
用于我左右的字符串父节点,而是想要一个空字符串。我是否必须为此创建一个新的构造函数?当我用 nullptr 替换 basic_string::_M_construct null not valid
时出现错误 ("NULL"
)。
#include <string>
#include <cstdlib>
#ifndef PRIORITY_NODE
#define PRIORITY_NODE
namespace Huffman
{
class PriorityNode
{
private:
std::string key; // The character sequence to compress
long frequency = 0; // The frequency of the character sequence
PriorityNode* left = (PriorityNode*)malloc(sizeof(PriorityNode));
PriorityNode* right = (PriorityNode*)malloc(sizeof(PriorityNode));
public:
PriorityNode(std::string k,long f): frequency(f),key(k){};
std::string getKey() const{ return key;}
long getFrequency() const{ return frequency;}
void setLeft(const PriorityNode& left){*this->left = left;}
void setRight(const PriorityNode& right){*this->right = right;}
PriorityNode& getLeft() const{ return *left;}
PriorityNode& getRight() const{ return *right;}
friend PriorityNode combine(const PriorityNode& lhs,const PriorityNode& rhs)
{
long ret_freq = lhs.getFrequency() + rhs.getFrequency();
PriorityNode ret = PriorityNode("NULL",ret_freq);
ret.setLeft(lhs);
ret.setRight(rhs);
return ret;
};
};
}
#endif
解决方法
所以几点。
-
key
是一个字符串,而不是一个指针。将它设置为nullptr
是没有意义的,我猜"NULL"
只是当key
没有价值时的替代品。而不是这样,只需使用一个空字符串""
。 -
出于多种原因,您应该尽量避免这种手动内存管理。首先,您没有析构函数,因此您的内存
malloc
永远不会free
ed,这意味着您有内存泄漏。其次,您为子节点分配内存,即使您不需要。我会建议更像以下内容:class PriorityNode { private: ... std::shared_ptr<PriorityNode> left,right; // Default constructs to nullptr ... friend PriorityNode combine(const std::shared_ptr<PriorityNode> lhs,const std::shared_ptr<PriorityNode> rhs) { PriorityNode ret = PriorityNode("",ret_freq); ret.setLeft(lhs); ret.setRight(rhs); return ret; };
空字符串是 ""
。您可以将其传递给现有的构造函数。 std::string
不像 C 字符串那样区分空字符串和 NULL 指针。不允许使用 NULL 指针初始化 std::string
。如果您需要单独的空状态,请使用 std::optional<std::string>
。