ASAN кучи использовать после бесплатно - PullRequest
0 голосов
/ 30 ноября 2018

Я использую ASAN для обнаружения утечек памяти в очень большом проекте.Я выяснил причину, но не знаю, как ее устранить.Я сделал пример программы, чтобы сделать проблему понятной.В приведенной ниже программе я могу обойти только указанный код.Для остальной части кода не возможно обойти.Поэтому, пожалуйста, предложите, что обходить мне, возможно, придется устранить ниже ошибки ASAN.(Как сделать указатель два как NULL, используя t1?)

#include<stdio.h>
#include<stdlib.h>

typedef struct l
{
    int a, b;
}pack;

void delete_me(pack *ap)
{
    free(ap);
}

int main(void)
{
    pack **d_ptr = (pack **)malloc(3 * sizeof(pack *));
    pack *one, *two, *three;
    one = (pack *)malloc(sizeof(pack));
    one->a = 1, one->b = 2;
    two = (pack *)malloc(sizeof(pack));
    two->a = 3, two->b = 4;
    three = (pack *)malloc(sizeof(pack));
    three->a = 5, three->b = 6;
    d_ptr[0] = one;
    d_ptr[1] = two;
    d_ptr[2] = three;

    // I can Only work-around below code (4 lines)
    pack *t1 = d_ptr[1]; // For which index t1 would be assigned, is not known before hand
    t1->a = 1; t1->b = 2;
    printf("a: %d, b: %d\n", two->a, two->b);
    delete_me(t1); // How to delete t1 so that corresponding pointer also becomes NULL?
    // Work around only till here was possible.

    // Below this, No workaround possible.
    if (two && (two->a == one->a)) // ASAN ERROR
            printf("ERROR\n");
    else
            printf("It works!\n");
    return 0;
}

Ошибка ASAN: ОШИБКА: AddressSanitizer: heap-use-after-free

1 Ответ

0 голосов
/ 21 июня 2019

К сожалению, ваша проблема на самом деле не решаема.

Если у вас есть несколько копий одного и того же указателя, например,

int *p1 = malloc(sizeof (int));
int *p2 = p1;
int *p3 = p2;

, то освобождение любого из них делает их недействительными:

free(p2);
// Now p1, p2, p3 have invalid values.
// The C standard calls these "indeterminate values"; accessing them has undefined behavior

Вы можете вручную установить p2 на NULL после освобождения, но это все равно оставляет повисшими p1 и p3.Вы не можете автоматически найти все копии значения указателя, которые могут существовать где-либо в памяти вашей программы.

Вам необходимо реструктурировать логику вашей программы.Там нет быстрого и легкого решения.

...