2010-09-09 48 views
2

我想在UNIX上通過串聯str1和str2來使用putenv()。 我想在環境中添加一個變量或修改一個變量,所以我打電話給putenv()(或者我可以同樣地調用setenv())。在UNIX上使用putenv()時出現問題()

基本上,我收到了str1和str2,我創建了str1 = str2並將它作爲參數傳遞給putenv()。

我顯示的代碼有效,但是當我取消註釋free()調用時,它不會:該變量不會被添加/修改爲環境。

size_t size = strlen(str1) + strlen(str2) + 2; // 2 is for the '\0' and the '=' 
char *tmp = (char *) malloc(sizeof(char) * size); 
char *p; 
int pos = 0; 

// Copy first word 
p = str1; 
while (*p != NULL) { 
    tmp[pos++] = *p++; 
} 

// Add the '=' 
tmp[pos++] = '='; 

// Copy second word 
p = str2; 
while (*p != NULL) { 
    tmp[pos++] = *p++; 
} 

// Add null character 
tmp[pos] = '\0'; 

int ret = putenv(tmp); 
if (ret != 0) { 
    perror("putenv failed"); 
} 

//free(tmp); // This line is the problem when not commented 

我爲代碼冗餘道歉,我知道兩個while循環是相同的。我的問題是,如果我取消註釋免費聲明,然後調用「env」打印環境,則putenv不會添加該值。

我不確定這是爲什麼。現在讓它工作,我有一個內存泄漏,我不喜歡。當我使用數組而不是指針時,它會產生與免註釋相同的問題。

任何想法?

回答

4

putenv()要求設置到環境中的字符串存在,因爲它不會複製字符串;它使用指向爲參數提供的字符串的指針。

這在運行putenv()的一個相當模糊的方式OpenGroup的描述指出:

http://www.opengroup.org/onlinepubs/009695399/functions/putenv.html

「A潛在誤差是調用運行putenv()用自動變量作爲參數,則返回從字符串仍然是環境的一部分的調用函數。「針對您的問題

兩個可能的解決方案是:

1 - 爲了得到你想要用putenv(),你可以使用一個靜態字符串,或以其他方式使用的字符串不出去的範圍,直到環境是什麼變量是不需要的。

2 - 或者,使用比putenv更易於使用的setenv(const char * envname,const char * envval,int overwrite),分配內存並複製字符串,並且不要求像您那樣連接字符串現在正在做。

+0

現貨 - 您必須放棄內存,並且如果您隨後更改環境變量的值,則容忍泄漏。基本上,如果你有'setenv()'可用,不要使用'putenv()'。現在是否存在帶有'putenv()'而沒有'setenv()'的系統是有爭議的; 10年前,使用'setenv()'更多的是可移植性責任 - 而'putenv()'是可靠的,但使用起來不會有泄漏的麻煩。 – 2010-09-09 06:41:20

+0

非常感謝您的幫助!我會切換到setenv(),非常感謝。 – Jary 2010-09-09 16:23:46

相關問題