обновление библиотеки C, получение повреждения кучи - PullRequest
0 голосов
/ 21 января 2012

Это дешевый хак, но я пытаюсь изменить метод размещения библиотеки C, над которой я работаю. По какой-то причине он использовал GlobalLock, возможно, потому что раньше это было несколько DLL. Я изменил его для выделения:

HANDLE BmiDibAlloc(size_t uBytes)
{   
    HANDLE alloc = malloc(uBytes + sizeof (size_t));

    if (alloc != NULL) 
    {
        memcpy_s(alloc, sizeof (alloc), &uBytes, sizeof (size_t));
    }

    return BmiDibAttach(alloc); //just tracks the number of memory allocs for logging
}

BOOL BmiDibFree(HANDLE hdib)
{
    if (!hdib) {
        return TRUE;
    }
    free(hdib);
    // Forget this handle:
    return BmiDibDetach(hdib);
}

Поскольку я больше не могу использовать GlobalSize, я обращаю внимание на размер выделения в первых байтах sizeof (size_t) ...

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

Ответы [ 2 ]

2 голосов
/ 21 января 2012

Когда вы выделяете блок, вы выделяете немного больше места, сохраняете свой заголовок в начале блока, а затем возвращаете указатель на смещение в блоке (а не в начале блока). Например, «вернуть alloc + sizeof (MY_HEADER)».

Когда вы освобождаете блок, вы должны делать обратное. Например:

BOOL BmiDibFree(HANDLE callerPointer)
{
    actualPointer = callerPointer - sizeof(MY_HEADER);
    free(actualPointer);

Примечание 1: Для повышения производительности вы должны убедиться, что sizeof (MY_HEADER) кратно минимальному выравниванию, предоставленному malloc (); таким образом, у вызывающего абонента не возникает проблем с выравниванием.

Примечание 2: Вы можете добавить «канареек» (магические числа) в реальном начале блока и в реальном конце блока и проверять их (во время free и realloc), чтобы увеличить вероятность обнаружения повреждения кучи. Я делаю это и устанавливаю флаг «куча была повреждена», и проверяю этот флаг перед любым malloc / free / realloc (если куча была повреждена, все последующие операции сразу завершаются неудачно, чтобы избежать увеличения беспорядка).

Примечание 3: Вы можете использовать условную компиляцию (например, "#ifdef DEBUGGING"), чтобы включить / отключить различные функции вашей оболочки. Я делаю это тоже - один для включения дополнительной проверки (канареек) и один для сбора / представления статистики (общее количество выделенных блоков, максимальное количество блоков, выделенных в любое время, общее количество выделенных байтов, максимальное количество байтов, выделенных в любое время).

0 голосов
/ 21 января 2012

В: Вы действительно имеете в виду «sizeof (size_t)»? Обычно это всего 4 байта. То же самое с "sizeof (alloc)" - вероятно, это просто "4".

...