2017-01-30 127 views
2

我想釋放一個變量列表的指針與freeS宏下面:freeS(s1,s2,...);免費沒有免費的指針作爲va_arg列表發送

儘管使用freeSF函數的第一個指針地址進行打印,但我的代碼並未釋放第一個指針。 主要,免費(s1)的作品,但它應該。免費(s2)在主要崩潰如預期。

如何釋放freeSF函數中的s1指針?

#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。它只發生在免費(s2) – Remy

+0

它不會導致錯誤:http://ideone.com/2sQPXl你仍然調用'free'兩次,這是未定義的行爲..不要調用'free(s1)當你已經在執行freeS(s1,s2)''時,''和'free(s2)'。 – Brandon

回答

6

您的程序展品undefined behavior,因爲你是雙重釋放。

由於未定義的行爲,任何事情都可能發生。你的程序可能會崩潰,它可能會輸出奇怪的結果,或者(在這種情況下)它可能會正常工作。添加一個看似無關的更改(例如調用printf或添加一個未使用的局部變量)可以改變未定義行爲的體現方式。

在這種情況下,在main中調用free(s1)不會導致崩潰。它仍然是未定義的行爲。例如,當我運行這段代碼時,它不會崩潰。但是如果我在致電free(s1)之前添加對malloc的呼叫,它確實會崩潰。

只因爲代碼可以崩潰並不意味着它

+0

正確,我寫的是一樣的,但是我在考慮爲什麼在主代碼中使用'free(s1)'加倍會導致錯誤,而使用OP代碼則不會。你有想法嗎? – LPs

+0

@LPs;這就是未定義行爲本身的定義。 OP的代碼可能會或可能會導致錯誤。它是未定義的。它可能適用於他,但它可能不適用。 – Brandon

+0

@Brandon嗯,我知道....只是出於好奇:如果這個UB有一個可解釋的行爲。 – LPs