Ошибка Malloc: неправильная контрольная сумма для освобожденного объекта

Я не знаю официального способа, но есть интересная техника, описанная в проблеме Terraform :

variable "values_list" {
  description = "acceptable values"
  type = "list"
  default = ["true", "false"]
}

variable "somevar" {
description = "must be true or false"
}

resource "null_resource" "is_variable_value_valid" {
  count = "${contains(var.values_list, var.somevar) == true ? 0 : 1}"
  "ERROR: The somevar value can only be: true or false" = true
}

9
задан j0k 18 September 2012 в 15:06
поделиться

6 ответов

Ваша стандартная программа пишет вне выделенного буфера строки.

Размер строки передал как аргумент (т.е. "len"), вероятно, не включает разделитель NUL. При вызове malloc для копирования строки (т.е. "s"), необходимо выделить дополнительный байт для строкового разделителя:

 *(lines + slot) = (char *) malloc((len + 1) * sizeof(char));
7
ответ дан 4 December 2019 в 20:26
поделиться

nlines и numlines имеют то же значение?

Вызывающая сторона insert_line предусматривает пространство для запаздывания NUL при передаче длины во втором параметре?

0
ответ дан 4 December 2019 в 20:26
поделиться

Если можно последовательно воспроизводить проблему с определенными входными параметрами, необходимо отладить как это:

  • Сначала отладьте к точному свободному, которое вызывает проблему.
  • Затем фигура, когда память, которая собирается быть free'd, была malloc'ed.
  • Затем, отладьте к месту, где память является malloc'ed.
  • Найдите в средстве просмотра памяти выделенный блок памяти. Отметьте и запуск и конец блока. Существует, вероятно, специальное значение, названное защитным блоком незадолго до и сразу после блока.
  • Теперь шаг через код до памяти является free'd. В какой-то момент Ваш код должен по ошибке перезаписать защитный блок. Это - незаконный оператор.

Обратите внимание, что проблема могла бы очень хорошо быть в совершенно другой части Вашей программы. Даже при том, что это - это свободное, который сообщает об ошибке, код, который перезаписывает защитный блок, может быть где угодно.

3
ответ дан 4 December 2019 в 20:26
поделиться

Мой первый вопрос состоит в том, как Вы вычисляете len? Это просто strlen, или это включает комнату для \0 разделителей? Я думаю, что можно промахиваться выделению в strcpy. Плохое поведение будет иметь тенденцию происходить на границах слова и казаться случайным. Кроме того, проверьте, чтобы удостовериться, что Ваши исходные строки пустые завершенный. Если Вы сделали ошибку на стороне чтения и не завершали их. Затем strcpy может случайным образом перезаписывать вещи.

  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
  strcpy(*(lines+slot),s);

Возможно, попытка:

  lines[slot] = (char *) malloc((len + 1) * sizeof(char));
  if(lines[slot] == NULL) exit(EXIT_FAILURE);
  if(strlen(s) <= len){
    strcpy(lines[slot],s);
  }
  else{
    /* do something else... */
  }

С точки зрения общей формы я также поощрил бы Вас вносить несколько стилистических изменений для создания всего этого более читаемым, легче следовать и стойкий к ошибкам.

Адресная арифметика с указателями допустима и забавна, но я думаю, что Ваше намерение немного более ясно при использовании формы массива как:

free(lines[slot]);
lines[slot] = NULL;

вместо

free(*(lines+slot));
*(lines + slot) = NULL;

Я также поощрил бы Вас использовать меньше помех. Достаточно легко через них в структуре данных и раздать их в Ваши средства доступа и мутаторы. Становится намного более ясно, где действие происходит, препятствует тому, чтобы Вы делали вещи как:

static int numlines = 0;
void insert_line(char *s, int len){
    int numlines = 5;

где можно представить проблемы обзора, которые просто скудны для отладки.

1
ответ дан 4 December 2019 в 20:26
поделиться

Я соглашаюсь с подозрением remo о тех двух строках, но не касательной, на которой ушел remo. Мы должны совместно использовать кредит на нахождение этой ошибки.

*(lines + slot) = some value
if((lines + slot) == NULL) then die
should be
if(*(lines + slot) == NULL) then die
0
ответ дан 4 December 2019 в 20:26
поделиться

Я не уверен, что это связано, но эти две строки кажется подозрительным мне:

  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if((lines + slot) == NULL) exit(EXIT_FAILURE);

Вы сначала присваиваете возврат malloc к lines[slot] и затем Вы проверяете (lines+slot), если последний был ПУСТЫМ, Вы имели, разыменовывают Нулевого указателя!

Также, если строки [слот] (Ваш * (lines+slot)) не будут пустыми, то Вы пропустите память при присвоении результата malloc () к нему.

Я принимаю lines a char*строки []' и слот в позволенной границе!

0
ответ дан 4 December 2019 в 20:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: