В 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. Меня удивляет сообщение об ошибке «Недопустимый размер». Почему я не могу разместить здесь более ~ 1950 байт?