Проблемы с кучей коррупции - PullRequest
2 голосов
/ 03 марта 2010

Внутри моей функции шаблона у меня есть следующий код:

TypeName myFunction()
{

    TypeName result;
    void * storage = malloc( sizeof( TypeName ) );

    /*Magic code that stores a value in the space pointed to by storage*/

    result = *(TypeName *)storage;

    free( storage );
    return result;
}

Это вызывает ошибку «HEAP CORRUPTION DETECTED». Если я не вызываю функцию free (), ошибка не возникает, но я боюсь, что я создаю утечку памяти. Что было бы правильным способом вернуть значение «хранилище», а затем освободить память?

Ответы [ 5 ]

3 голосов
/ 03 марта 2010

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

void magic(void *buffer)
{
  // magic stuff 
}

TypeName foo()
{
   TypeName result;
   magic(&result);
   return result;
}

Или, конечно, вы можете настроить структуру TypeName как битовые поля или что-то еще, чем манипулирует ваш магический код ...

2 голосов
/ 03 марта 2010

не называйте это так:

TypeName result;
void * storage = malloc( 4 );

Вы должны назвать это

TypeName result;
void * storage = malloc( sizeof(TypeName) );

в любом случае код выглядит странно:)

1 голос
/ 03 марта 2010

А как же:

TypeName myFunction() {
    TypeName result;
    void* storage = &result;

    /*Magic code that stores a value in the space pointed to by storage*/

    return result;
}

Здесь все ваши переменные будут храниться в стеке, поэтому вы не должны сталкиваться с проблемами, связанными с кучей (в зависимости от того, что именно делает ваш «волшебный» код).

Есть ли причина, по которой ваш массив storage отделен от result? Если результаты будут просто скопированы в result, было бы более разумно (IMHO) использовать только один объект (и либо сохранять указатель void* на него, либо приводить тип &result по мере необходимости).

Если есть причина использовать отдельные storage и result, вы, вероятно, получите лучший пробег, используя TypeName storage = new TypeName и delete вместо malloc(4) и free.

1 голос
/ 03 марта 2010

Я думаю, что ваша путаница заключается в этой строке:

 void * storage = malloc( 4 );

Похоже, вы пытаетесь выделить место для 4-байтового указателя, но это не то, что вам нужно делать. Давайте разберем строку в два этапа:

void * storage;          // This allocates 4 bytes for a variable of type "pointer to void"
storage = malloc( 4 );   // This allocates 4 _more_ bytes and sets "storage" to their address.

Я предполагаю, что «магический» код копирует данные из переменной типа Typename в память, выделенную для storage, с таким эффектом:

memcpy(storage, data_from_a_Typename_variable, sizeof(Typename));

Таким образом, если sizeof(Typename) больше, чем 4 байта, которые были выделены для storage, вы увидите ошибку повреждения кучи.

Как показывают другие ответы, вам нужно выделить достаточно места для переменной Typename, например:

void * storage = malloc(sizeof(Typename));

Но, как предложила Лиз Альбин , вы уже выделили пространство для Typename в result, поэтому проще передать &result или (void *) &result в магическую функцию.

0 голосов
/ 03 марта 2010

Почему вы malloc с 4 байтами и все же приводили к имени типа TypeName? Это определенно выглядит странно!

Другие ответы намекают вам, что это ...!

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

...