malloc (): недопустимый размер (не отсортирован) для нового неподписанного символа [<size>] - PullRequest
1 голос
/ 02 октября 2019

В 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 байт?

...