2017-01-30 9 views
2

Я хочу освободить список переменных указателя с помощью макроса freeS ниже: freeS (s1, s2, ...);Бесплатно не бесплатные указатели, отправленные в виде списка va_arg

Мой код не освобождает первый указатель, несмотря на получение печати с первым адресом указателя из функции freeSF. В основном, бесплатно (s1) работает, но он должен. free (s2) в основных авариях, как ожидалось.

Как я могу освободить указатель s1 в функции freeSF?

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

#define freeS(...) freeSF("", __VA_ARGS__, NULL) 
void freeSF(char *paramType, ...) { 
    va_list pl; 

    va_start(pl, paramType); 
    paramType = va_arg(pl, char *); 
    while (paramType) { 
     printf("arg %p\n", paramType); 
     free(paramType); 
     paramType = va_arg(pl, char *); 
    } 
    va_end(pl); 
} 

int main(int ARGC, char** ARGV) { 
    char *s1 = strdup("1"); 
    char *s2 = strdup("2"); 
    printf("s1 %p, s2 %p\n", s1, s2); 
    freeS(s1, s2); 
    free(s1); 
} 
+2

Вы выполняете: 'freeS (s1, s2)', а затем выполняете 'free (s1)'. Вы удваиваете свободу. http://ideone.com/shZ3Sc работает отлично. Откуда вы знаете, что это не освобождает? – Brandon

+0

Если указатель двоичный, появляется ошибка: Ошибка в './a.out ': двойная свобода или коррупция (fasttop): 0x00000000024c5030. Это происходит только для free (s2) – Remy

+0

Это не вызывает ошибки: http://ideone.com/2sQPXl Вы все еще вызываете 'free' дважды, и это неопределенное поведение. Не называйте' free (s1) 'и' free (s2) ', когда вы уже выполняете' freeS (s1, s2) '.. – Brandon

ответ

6

Ваша программа показывает undefined behavior, потому что вы являетесь двойным освобождением.

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

В этом случае вызов free(s1) в main не вызывает крушения. Это все еще неопределенное поведение. Например, когда я запускаю этот код, он не падает. Но если я добавлю вызов malloc непосредственно перед вызовом free(s1), он сработает.

Просто потому, что код может авария не означает его будет.

+0

Правильно, я писал то же самое, но я думал, почему удвоение 'free (s1)' в основном вызывает ошибку, в то время как с OP-кодом нет. У вас есть представление об этом? – LPs

+0

@LPs; Это определение неопределенного поведения само по себе. Код OP MAY или MAY-NOT вызывает ошибку. Он не определен. Это может сработать для него, возможно, нет. – Brandon

+0

@Brandon Ну, я знаю ... Просто из любопытства: если этот UB имеет объяснимое поведение. – LPs