Вызов функции free приводит к тому, что программа выдает исключение

#c #windows #multithreading #api #free

#c #Windows #многопоточность #API #Бесплатно

Вопрос:

Я делал свою домашнюю работу, когда наткнулся на следующую проблему. Я должен создать простое многопоточное приложение, используя C и используя функции Windows API. Каждый поток выполнял бы простую задачу, поэтому я решил переработать некоторые старые вещи, которые я сделал.

У меня есть файл заголовка:

http://pastebin.com/1aJFAwBg

И исходный файл:

http://pastebin.com/L127FGhG

Затем в main я выполняю следующий вызов:

 LoadPoem();
ProcessPoem();
SavePoem();
  

LoadPoem открывает файл, содержащий оригинал, выделяет буфер для ввода (переменная loadedPoemBuffer) и сохраняет в нем текст из файла. Затем ProcessPoem выделяет буфер для измененной версии (переменная processedPoemBuffer ) и заполняет его путем повторного вызова strtok . Затем он освобождает loadedPoemBuffer и завершает работу.
Пока все хорошо.
Проблема возникает, когда я вызываю SavePoem() , он правильно сохраняет данные, но когда он заканчивается, он вызывает free(processedPoemBuffer) и выдает кучу, поврежденную исключением. Кажется, я не могу понять, почему. Мне кажется, что он выполняет точно ту же операцию, что и ProcessPoem перед ним, но эта функция не завершается сбоем.

Может кто-нибудь, пожалуйста, объяснить мне это? Заранее благодарю.

Комментарии:

1. Во-первых: прошу прощения за опечатки, английский не является моим родным языком. Во-вторых: я не понимаю, что вы имеете в виду. Это не все, просто фрагмент кода для выполнения одного из потоков. Если это то, что вы имели в виду под своим комментарием. Если это так — извините, что не указал это в первый раз.

2. Нет, это не проблема с опечатками, просто многопоточность не считается простой, на самом деле наоборот, известно, что она увеличивает сложность.

3. Я знаю, но назначение было для многопоточной программы. И он должен запускать только 2 потока. Но вы определенно правы.

Ответ №1:

processedPoemBuffer имеет значение LPWSTR, что означает, что ваши данные в Юникоде. Затем вы вызываете _tcscat_s, который, если вы создаете для Unicode, ожидает количество символов, а не байтов. Вам нужно разделить размер вашего входного файла на размер WCHAR для аргумента длины буфера _tcscat_s.

Комментарии:

1. В ProcessPoem вы могли бы сделать что-то вроде: DWORD outputMax = (inputFileSize 2) / sizeof(*processedPoemBuffer); Затем используйте outputMax в ваших вызовах _tcscat_s. Вы также можете использовать wcscat_s, поскольку вы знаете, что ваши данные содержат широкие символы

2. Ага. Я кратко рассмотрел это ранее и сразу заподозрил проблему с размером буфера, но не стал искать дальше. Вы сделали, так что 1

Ответ №2:

Исключение в free означает, что вы вызываете его с чем-то, что не является результатом a malloc . Инициализируйте ваше processedPoemBuffer значение с помощью NULL и проверьте его на free :

 void* processedPoemBuffer = NULL;
...
if (some_err) goto error;
... 
error:
if (processedPoemBuffer) // only delete checks for NULL
    free(processedPoemBuffer);
  

Комментарии:

1. -1 : Если нулевой указатель передается в качестве аргумента в free, никаких действий не происходит.

2. Я не думаю, что это так. Он определенно выделяется с помощью malloc, а затем освобождается. И только один раз. Возможно, будет лучше передавать массивы как входные / выходные параметры и выполнять фактическое распределение в main.