Ошибка со свободной функцией после malloc

Приведенный ниже код приводит к падению C++ в строке: free (arg). Я пытаюсь предотвратить утечку памяти, но мне не удается освободить данные, которые я храню в куче памяти. Может кто-нибудь помочь мне с этой проблемой?

Обратите внимание, что free(args) работает нормально.

#include "stdafx.h"
#include <process.h>
#include <iostream>

#include <windows.h>

using namespace std;

typedef struct {
    int StartNode;
    int EndNode;
}t;
t *arg;

void myFunc(void *param) {
    t *args = (t*)param;
    int x = args->StartNode;
    int y = args->EndNode;
    printf("x=%d, y=%d\n", x, y);
    free(args);
    free(arg);
}

int main()
{
    HANDLE handle;
    arg = (t *)malloc(sizeof(t));
    arg->StartNode = 101;
    arg->EndNode = 103;
    handle = (HANDLE)_beginthread(myFunc, 0, (void*)arg);
    cin.get();
    return 0;
}

2 ответа

Решение

Ваши оба указателя соответственно args а также arg указывают на одну и ту же область памяти, и вы пытаетесь освободить одну и ту же область памяти дважды, и это создает проблему здесь. Пожалуйста, смотрите ниже:-

 free(args); //args->arg here args is pointing to arg you have just type cast it from void
 free(arg);//you have already release the memory in the above call so this is wrong

Просто попробуйте вот так для понимания, ниже пример не решение, а для вашего понимания. Здесь вы назначаете args = NULL и это будет отражено в arg = NULL следовательно if(arg != NULL) будет ложным и, следовательно, free(arg); не будет звонить.

free(args); 
args = NULL;
if(arg != NULL)
  free(arg);

Оба аргумента и аргументы указывают на одно и то же место в памяти. Достаточно бесплатного звонка по любому.

Количество бесплатных звонков должно быть таким же, как у malloc. вы используете conde только один раз, в

arg = (t *)malloc(sizeof(t));

но вы освобождаете один и тот же адрес дважды:

free(args);
free(arg);

Теперь это код на C, а не на C++ (в качестве C++ вы бы использовали new / delete или, что еще лучше, вы бы не использовали ни new, ни delete, а передавали переменные через стек в виде ссылки следующим образом:

#include <iostream>
#include <windows.h>

struct MyType {
    int StartNode;
    int EndNode;
};

void myFunc(const MyType &param) {
    const auto x = args.StartNode;
    const auto y = args.EndNode;
    std::cout << "x=" << x << ", y=" << std::endl;
}

int main()
{
    auto arg = MyType{};
    arg.StartNode = 101;
    arg.EndNode = 103;
    std::thread thread(myFunc, arg);
    thread.join();
    cin.get();
    return 0;
}

Несколько случайных заметок:

  • вы смешиваете C с C++, это не тот же язык
  • Вы используете вызовы только для Windows, используйте стандартный (как в примере потока)
  • не используйте использование пространства имен std; это делает код нечитаемым в кратчайшие сроки.
Другие вопросы по тегам