2010-07-07 68 views
0

忍受我。我在8年內沒有用c語言編碼,而且完全困惑爲什麼我的字符串操作不起作用。我正在編寫一個永久循環的程序。在循環中,我初始化了兩個char指針,每個指針都被傳遞給一個將文本添加到char指針(數組)的函數。當函數完成後,我打印字符指針並釋放兩個字符指針。但是程序後,7次迭代死與以下錯誤消息realloc和自由原因「雙免費或腐敗」

* glibc的檢測* ./test:雙重釋放或腐敗(fasttop):0x0804a168 ***

#include sys/types.h 
#include sys/stat.h 
#include fcntl.h 
#include string.h 
#include stdio.h 
#include stdlib.h 
#include errno.h 
#include time.h 

char *SEPERATOR = "|"; 

void getEvent (char* results); 
void getTimeStamp(char* timeStamp, int timeStampSize); 
void stringAppend(char* str1, char* str2); 

int main (int argc, char *argv[]) 
{ 
    int i = 0; 
    while(1) 
    { 
    i++; 
    printf("%i", i);  

    char* events= realloc(NULL, 1); 
    events[0] = '\0'; 
    getEvent(events); 

    char* timestamp= realloc(NULL, 20); 
    timestamp[0] = '\0'; 
    getTimeStamp(timestamp, 20); 

    printf("%s", events); 
    printf("timestamp: %s\n", timestamp); 

    free(events); 
    free(timestamp); 
    } 
} 

void getEvent (char* results) 
{ 
    stringAppend(results, "a111111111111"); 
    stringAppend(results, "b2222222222222"); 
} 

void getTimeStamp(char* timeStamp, int timeStampSize) 
{ 
    struct tm *ptr; 
    time_t lt; 
    lt = time(NULL); 
    ptr = localtime(&lt); 
    int r = strftime(timeStamp, timeStampSize, "%Y-%m-%d %H:%M:%S", ptr); 
} 

void stringAppend(char* str1, char* str2) 
{ 
    int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1; 
    printf("--%i--",arrayLength); 

    str1 = realloc(str1, arrayLength); 
    if (str1 != NULL) 
    { 
    strcat(str1, SEPERATOR); 
    strcat(str1, str2); 
    } 
    else 
    { 
    printf("UNABLE TO ALLOCATE MEMORY\n"); 
    } 
} 
+0

請重新格式化:) – KevinDTimm 2010-07-07 03:26:47

+0

@Kevin,如你所願。 – 2010-07-07 03:30:11

+0

你爲什麼每次分配循環而不是簡單地分配和重用內存? – 2010-07-07 03:31:42

回答

4

問題是,雖然stringAppend重新分配指針,但只有stringAppend知道這個事實。您需要修改stringAppend以獲取指針指針(char **),以便更新原始指針。

+2

或者,它可能只是返回'str1'的新值(因爲它不會嘗試重新分配'str2')。 – caf 2010-07-07 04:03:37

7

你正在重新分配str1但不會將值傳遞出您的函數,因此潛在更改的指針會泄漏,並且由您自由釋放舊值,該值已由realloc釋放。這會導致「雙重免費」警告。

4

這條線在stringAppend:

str1 = realloc(str1, arrayLength); 

改變stringAppend局部變量的值。這個名爲str1的局部變量現在指向重新分配的內存或NULL。

同時,getEvent中的局部變量保留之前的值,現在通常指向釋放內存。

1

所有評論都非常有幫助。當然,爲了發現錯誤,總是很重要的。我最終通過做出以下更改來解決它。

對於getEvent和stringAppend,我都返回字符指針。

例如

char* stringAppend(char* str1, char* str2) 
{  
    int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1; 
    printf("--%i--",arrayLength); 

    str1 = realloc(str1, arrayLength); 
    if (str1 != NULL) 
    { 
    strcat(str1, SEPERATOR); 
    strcat(str1, str2); 
    } 
    else 
    { 
    printf("UNABLE TO ALLOCATE MEMORY\n"); 
    } 
    return str1; 
} 
0

這不是一個回答你的問題(你並不需要一個,因爲錯誤被指出的),但我對你的代碼的一些其他意見:

char* events= realloc(NULL, 1); 
events[0] = '\0'; 

你不測試realloc成功分配內存。

char* timestamp= realloc(NULL, 20); 
timestamp[0] = '\0'; 

同樣的問題在這裏。在這種情況下,根本不需要realloc。由於這是一個固定大小的緩衝區,你可以只使用:

char timestamp[20] = ""; 

而且不這樣做:

str1 = realloc(str1, arrayLength); 

,因爲如果realloc失敗了,你會是孤立在str1指向內存到之前。相反:

char* temp = realloc(str1, arrayLength); 
if (temp != NULL) 
{ 
    str1 = temp; 
    ... 
} 

注意,因爲你正在修改stringAppend返回新的字符串,你應該做的通話功能類似的檢查。

此外,「分隔符」拼寫爲兩個As,而不是兩個Es。