Intereting Posts
Могу ли я заблокировать и разблокировать fifo (named pipe) в C? Указатели и дерево двоичного поиска Портативный способ проверить, является ли указатель char * строкой с нулевым завершением const char ** a = {“string1”, “string2”} и указательный арифметический Преобразовать backtrace libc в номер строки источника Динамический параллелизм CUDA MakeFile Программно проверить сертификат X509 и совпадение с закрытым ключом Можно ли проверить, равен ли какой-либо из двух наборов из 3 целых чисел менее 9 сравнений? gcc не включает внешние переменные в таблице символов при использовании оптимизации сбор ошибок против статической библиотеки Избегание переполнения переполнения с помощью функций перестановки (nPr, nCr) в C Есть ли способ получить текст как можно скорее, не дожидаясь новой строки? Как протестировать мою программу по файлу тестового файла ввода Поведение функции Strlen для одного символа Почему scanf принимает неверный ввод для больших чисел с плавающей запятой?

Обнаружено повреждение кучи: после нормального блока

«CRT обнаружил, что приложение записало в память конец буфера памяти». Он падает, когда он прибывает на free . Любая помощь приветствуется.

 int messageFunction(char* message) { char* sPtr = strstr(message,"Subject:"); char* cPtr = strstr(message,"Content:"); char* messageSubject = (char*) malloc(cPtr - sPtr - strlen("Subject:")) char* messageContent = (char*) malloc(strlen(cPtr + strlen("Content:"))) strncpy(messageSubject, stPtr + strlen("Subject:"), cPtr - sPtr - strlen("Subject:")); messageSubject[cPtr - sPtr - strlen("Subject:")] = '\0'; strncpy(messageContent, cPtr + strlen("Content:"), strlen(cPtr + strlen("Content:"))); ... free(messageSubject); free(messageContent); } void main() { char* message = "Subject:HelloWorldContent:MessageContent"; int result = messageFunction(message); } 

Вы выделяете память, которая является слишком коротким. Ваши вычисления рассчитаны на длину данных между «Темами» и «Контент:», но не учитывают необходимость нулевого терминатора в строке. Затем, когда вы вручную добавляете нулевой ограничитель, вы вызываете неопределенное поведение, записывая конец конца массива.

Изменение вашего кода на следующее должно устранить его.

 char* messageSubject = malloc(cPtr - sPtr - strlen("Subject:") + 1) char* messageContent = malloc(strlen(cPtr + strlen("Content:")) + 1) 

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

Если вы это сделаете:

 char* v = malloc(n); 

то действительные индексы v варьируются от v[0] до v[n-1] . В частности, v [n] никогда не действует . Это общее правило. Если вы снова посмотрите на свой код, вы должны увидеть проблему.

Несколько примечаний:

  1. В вашем коде предполагается, что Subject: предшествует Контенту: и что оба они существуют. В некоторых случаях это предположение не будет корректным. Вы должны проверить, прежде чем запускать malloc’ing огромные объемы памяти (поскольку маленькие отрицательные числа превращаются в огромные положительные числа без знака). Вы также должны убедиться, что ваши mallocs не возвращают 0, а не segfault, когда они это делают.

  2. strdupstrndup ) часто избавит вас от неловкости «oops, я не выделил достаточно места для ошибок NUL byte». Они также не требуют почти столько же времени, что делает ваш код более простым, надежным и понятным. Познакомьтесь с ними. Они будут твоими друзьями.

  3. Если ничего не работает, valgrind может помочь вам найти такие ошибки.