首页 > 解决方案 > malloc():新无符号字符上的大小无效(未排序)[]

问题描述

SO上有大量与内存错误相关的帖子,但没有一个能解决我的问题。

考虑这个类(定义和声明合并以便于阅读):

#define SIZEMACRO(mem) *reinterpret_cast<uint32_t *>(mem)
class StoredRecord {
  uint64_t idx;
  unsigned char* mem;
 public:
  ~StoredRecord() { 
    delete[] mem;
  }

  StoredRecord() : idx(0), mem(nullptr) {}

  StoredRecord(uint64_t _idx, unsigned char* _mem) : idx(_idx), mem(new unsigned char[SIZEMACRO(_mem)]) {
    memcpy(mem, _mem, SIZEMACRO(_mem));
  }

  static std::shared_ptr<StoredRecord> createShared(uint64_t _idx, unsigned char* _mem) {
    return std::make_shared<StoredRecord>(_idx, _mem);
  }

  // Some getter for idx and mem
};

它没有做太多,占用内存并使用SIZEMACRO()(它将第一个字节评估为 uint32_t 并将其用作大小,效果很好)来确定内存块的大小,分配相同的大小并复制它。

这些StoredRecord被保存在std::vector<std::shared_ptr<StoredRecord>> m_records另一个类中。这里没有问题。但是,代码在使用时会崩溃,如下所示:

const uint32_t a = 1800;
const uint32_t b = 1900;
const uint32_t c = 2000;
unsigned char data1[a]; 
unsigned char data2[b];
unsigned char data3[c];
memset(data1, 0, a);
memset(data2, 0, b);
memset(data3, 0, c);
memcpy(data1, &a, sizeof(uint32_t));
memcpy(data2, &b, sizeof(uint32_t));
memcpy(data3, &c, sizeof(uint32_t));
m_records.push_back(StoredRecord::createShared(0, data1)); // fine
m_records.push_back(StoredRecord::createShared(1, data2)); // fine

// crashes with "malloc(): invalid size (unsorted)"
// at mem(new unsigned char[SIZEMACRO(_mem)])
m_records.push_back(StoredRecord::createShared(2, data3)); 

但是,如果我减少c = 1900一切都很好。当 a、b 或 c 高于 ~1950 时,它会malloc invalid size在使用 GDB 运行或正常运行时崩溃。我也用 valgrind 运行了我的代码,没有发生崩溃,它甚至没有抱怨new unsigned char。我已经仔细检查了SIZEMACRO()它,它对 1800、1900 和 2000 的评估都很好。让我感到困惑的是错误消息“无效大小”。为什么我不能在这里 malloc 超过 ~1950 字节?

标签: c++mallocvalgrind

解决方案


推荐阅读