2015-09-01 7 views
1

я создаю новый struct SThreadInfo в функции:Удаление памяти, на которую указывает пустой указатель

struct SThreadInfo { 
    int    function; 
    Exchange*  pThis; 
}; 

struct SThreadInfo *threadInfo = new (struct SThreadInfo); 
    threadInfo->function = 0; 
    threadInfo->pThis  = this; 

Тогда, в одной и той же функции, я создаю новый поток передать как-структуру ничтожной-указатель:

pthread_t ret; 
pthread_create(&ret, NULL, Exchange::staticThreadHelper, (void*)threadInfo); 

В новом потоке, я перестраивать-структуру из пустой-указатель:

void* Exchange::staticThreadHelper(void* t) 
{ 
    struct SThreadInfo* threadInfo = (struct SThreadInfo*)t; 
    //.... 
    //.... 
} 

В конце этой функции я хочу удалить память, выделенную t и threadInfo. К настоящему времени, он работает для threadInfo, но не для t

delete threadInfo; 
delete static_cast<struct SThreadInfo*>(t); 

Когда я пытаюсь бросить пустоты указателя обратно в SThreadInfo, SIGABRT поднимается. Может ли кто-нибудь сказать мне, как правильно удалить память из указателя void?

+0

@CaptainObvlious: Действительно? Разумеется, компилятор должен жаловаться на точку компиляции в этом случае. Проблема не в том, что у «двойного удаления», другими словами, OP пытается дважды удалить один и тот же объект? –

+0

Посмотрите на последний фрагмент кода - я пытаюсь использовать static_cast – Bobface

+0

Похоже, вы удаляете память дважды: один раз через t и один раз через threadInfo. Поскольку threadInfo - это всего лишь тэг t, оба указывают на один и тот же объект, который можно удалить только один раз. – antlersoft

ответ

7

Линия:

struct SThreadInfo* threadInfo = (struct SThreadInfo*)t; 

не «восстановить» ничего, он просто присваивает тип отлиты значение объявленной переменной. Это тот же указатель.

В конце функции вы, кажется, дважды удаляете (освобождаете) тот же адрес, и именно поэтому вы получаете свое исключение.

+0

Спасибо! На самом деле довольно очевидно: D – Bobface

2

Итак, проблема в том, что у вас есть ОДИН кусок памяти, у вас есть два разных указателя.

Вы должны только освобождать выделенную память ОДНИМ. Если у вас есть объект с деструктором [включая те, которые вызывают разрушение, например, что-то, содержащее другой объект с деструктором, например std::string или std::vector], вы должны убедиться, что звонок delete сделан с правильным типом.

В этом случае delete static_cast<SthreadInfo*>(t); или delete threadinfo; должен сделать трюк. Пытаясь до delete, одна и та же память более одного раза приведет к неопределенному поведению [видимо, ваша библиотека времени выполнения обнаруживает это и прервала выполнение].

+0

'delete threadInfo;' также будет работать, так как 'threadInfo' набирается как' struct SThreadInfo * 'и поэтому вызовет тот же деструктор, что и' delete static_cast (t); '. Просто не называйте оба оператора 'delete', так как они являются двумя указателями на один и тот же блок памяти, которые должны быть освобождены только один раз. –

+0

С поправкой ..... –

Смежные вопросы