从堆中删除失败
Failure deleting from heap
>我正在使用 SSO 制作一个字符串,当字符串超过 23 个字符时,我想将指向堆内存的指针存储在堆栈数组中。我遇到的问题是,当我尝试删除堆上分配的内存时出现错误。我知道我在正确的地址上调用删除,但它失败了。有谁知道为什么?代码如下:
class kstring
{
public:
kstring()
{
}
kstring(const char* str)
{
size_ = std::strlen(str);
if (size_ + 1 > capacity_)
reserve(capacity_ + 1);
std::strcpy(data(), str);
}
void reserve(size_t capacity)
{
if (capacity <= capacity_ || capacity <= 24)
return;
char* alloc = new char[capacity];
std::cout << "Alloc: " << static_cast<void*>(alloc) << std::endl;
std::copy(data(), data() + size_, alloc);
if (on_heap())
delete[] data();
std::memcpy(data_, &alloc, sizeof(char*));
capacity_ = capacity;
}
char* data()
{
return capacity_ > 24 ? heap_ptr() : data_;
}
size_t size() const noexcept
{
return size_;
}
size_t capacity() const noexcept
{
return capacity_;
}
char& operator[](size_t n)
{
return data()[n];
}
~kstring()
{
if (on_heap())
{
std::cout << "Deleting: " << static_cast<void*>(data()) << std::endl;
delete[] data();
}
}
bool on_heap()
{
return capacity_ > 24;
}
char* heap_ptr()
{
char* ptr = nullptr;
std::memcpy(&ptr, data_, sizeof(char*));
return ptr;
}
char data_[24] = {0};
private:
size_t size_ = 0;
size_t capacity_ = 24;
};
int main()
{
{
kstring str("Lorem ipsum dolor sit amet, consectetur adipiscing elit");
}
return 0;
}
解决方案:在构造函数中,我分配了 capacity_ + 1
字节而不是 size_ + 1
字节,从而导致堆损坏。
kstring(const char* str)
{
size_ = std::strlen(str);
if (size_ + 1 > capacity_)
reserve(capacity_ + 1);
std::strcpy(data(), str);
}
这有很多问题。
首先,您将size_
设置为立即的大小。但是如果你看一下 reserve
,它会尝试复制字符串中已有内容的size_
字节。
其次,您尝试保留的金额是 capacity_ + 1
.但是没有理由认为这足以容纳您将要复制的字符串。
这可能更接近您想要的:
kstring(const char* str)
{
size_t new_size = std::strlen(str) + 1;
if (new_size > capacity_)
reserve(new_size + 1);
std::strcpy(data(), str);
size_ = new_size - 1;
}
请注意,在调用 reserve
之前我们不会更改size_
,因此它不会越界访问。还要注意,我们告诉reserve
我们需要保留的正确字节数。
相关文章:
- 在c++中删除内存失败
- 使用已删除的函数进行编译失败,并显示 uclibc
- C++擦除-删除类型推断失败
- 简单的链接列表删除失败
- C 删除[]仅在发布版本中失败
- C++ 为什么不使用已删除的函数时编译器失败并显示错误代码 C2280
- 运行时检查失败#2 - 变量周围的堆栈'myArray'已损坏.- 似乎无法弄清楚如何删除此错误
- 使用GDI+删除位图和CLSID对象时,C++内存管理失败
- 从堆中删除失败
- 删除每个API呼叫的文件夹都会使用ERROR_ACCESS_DENIED失败
- 使用自定义删除程序返回unique_ptr的 nullptr 失败
- 删除数组时断言失败
- 删除SDL_VideoInfo指针时调试断言失败
- C++can运算符删除失败,如果不是原因
- 为什么当我删除此字符 * 时,调试断言失败block_type_is_valid
- 删除对象时调试断言失败
- 模板化的出列无效指针:删除类时失败
- 为什么以这种方式删除 2D 数组会失败(C++)
- 尝试删除失败
- 删除 [] 在 Linux 中放置新对象失败