我現在正在處理的是來自流的任何輸入的基於狀態的解析器。我的教授告訴我這是避免特殊情況的最好方法。我設置的方式是使用函數,並且在嘗試重用分配的內存時遇到了一些麻煩,所以我不會造成任何泄漏。我解析的是多個參數。每個參數都有一個名稱和一個值。一個示例的輸入將是:如何回收和重新使用分配的內存?
parameterName = 500;
名爲參數名稱和它的類型是整數的與的值。
我成功地能夠解析其中的一個沒有內存泄漏。但是,做第二個參數會導致泄漏,我知道爲什麼:這是我的參數名稱上多次使用malloc。
看看解析代碼:
int main()
{
int x;
char c;
char *nameTemp;
int hasName = 0;
int hasEqual = 0;
/* ParameterManager values */
ParameterManager *pm;
pm = PM_create(500);
if((PM_manage(pm, "name", INT_TYPE, 1)));
while((x = getchar()) != EOF)
{
/* Cast int to char */
c = (char)x;
/* Whitespace state */
if((isspace(c)))
{
c = whitespace();
}
/* Comment state */
if(c == '#')
{
c = comment();
}
/* Name state */
if(((isalnum(c)) && hasEqual == 0 && hasName == 0))
{
nameTemp = name(c);
printf("Name: %s\n", nameTemp);
hasName = 1;
}
/* Equal state */
if(c == '=' && hasName == 1 && hasEqual == 0)
{
hasEqual = 1;
}
/* Value state */
if((isalnum(c)) && hasName == 1 && hasEqual == 1)
{
getValues(c, nameTemp, pm->t_List, pm->m_List);
hasName = 0;
hasEqual = 0;
}
}
free(nameTemp);
if((PM_destroy(pm)) && DEBUG) printf("Success destroying PM.\n");
return 0;
}
線nameTemp = name(c)
,/* Name state */
下,返回一個分配的字符串。這個字符串稍後傳遞給其他工作。但是,由於這個整個解析思路處於循環中,因此將會創建多個mallocs。我只能免費nameTemp一次,但有多個mallocs這個名字。我如何重複使用nameTemp而不會導致泄漏?
下面是一段代碼(在功能name()
),其中nameTemp分配:
/* Make sure temp is not NULL before mallocing */
if(temp[0] != '\0')
{
returnName = malloc(sizeof(char)*strlen(temp)+1);
strncpy(returnName, temp, strlen(temp)+1);
temp[0] = '\0';
return returnName;
}
我道歉,如果一些事情都不清楚。我想盡可能地做到一般,所以如果你需要更多的澄清,請讓我知道。
如果我再次使用指針,釋放指針不是非法的嗎?如果我將** free(tempName)**放在身體末端,下次收集參數名稱時,它會給我一個錯誤。還是我不在同一頁上? – Plaidypus 2015-02-07 23:57:55
@Plaidypus:你將實際的分配內存塊混淆了「指針」(這是一個指向某個內存的變量)。同一塊內存*兩次釋放是非法的。但是,您可以將變量用於不同的事情,並且在這樣的循環中,它是非常有意義的。 – 2015-02-08 00:05:38
@Plaidypus不,這很好。在你釋放它之後使用相同的指針**地址**是未定義的行爲(除非它再次被'malloc'返回,這是完全可能的),但包含指針地址的變量具有自動存儲持續時間並且可用該函數退出。 – IllusiveBrian 2015-02-08 00:05:51