2017-06-16 21 views
0

我知道這已經有很多問題了,但是我看到的每個例子看起來都不符合。在下面的代碼中,如果我保留free(),則會生成編譯後的二進制段錯誤。如果我刪除它,代碼工作得很好。我的問題是,爲什麼?簡單的c函數,免費的段錯誤

int convertTimeToStr(time_t* seconds, char* str) 
{ 
    int rc = 0; 

    if (str == NULL) { 
     printf("The passed in char array was null!\n"); 
     rc = 1; 
    } else { 
     char* buf = malloc(sizeof(char) * 100); 
     memset(buf, '\0', sizeof(buf)); 

     buf = asctime(gmtime(seconds)); 
     strcpy(str, buf); 

     free(buf); 
    } 

    return rc; 
} 
+5

請勿使用嵌入的行號碼發佈代碼:( –

+0

更改'memset(buf,'\ 0',sizeof(buf));'將'memset(buf,'\ 0',100 * sizeof (char));' –

+0

'sizeof(buf)'與sizeof(char *)'相同,在我的機器上爲8 –

回答

3

的問題是,你重新分配指針您分配的內存。你在做什麼基本上等同於

int a = 5; 
int b = 10; 
a = b; 

,然後不知道爲什麼a不再等於5

隨着賦值buf = asctime(gmtime(seconds))你失去了原來的指針,並有內存泄漏。

asctime函數返回的是指向靜態內部緩衝區的指針,它不是你應該傳遞給free的東西。

+0

因此,適當的位然後是放棄整個buf部分,而不是執行strcpy(str,asctime(gmtime(seconds))); 是否正確? – vergessen

+0

@vergessen是的,這是最簡單的解決方案。 –

2

您不應該對此感到驚訝,因爲您已將指針buf的值從malloc()返回的值改爲。

char* buf = malloc(sizeof(char) * 100); // value returned by malloc() 
memset(buf, '\0', sizeof(buf)); 
buf = asctime(gmtime(seconds));   // change value of buf 
strcpy(str, buf); 
free(buf);        // buf differs from above 

調用free()與不是從malloc()(或稱之爲第二次)返回一個說法是不確定的行爲。

+0

謝謝......我很樂意將所有這些標記爲答案,因爲它們都有助於放大圖片(至少,以幫助我在c中的理解)。 – vergessen

1

你叫mallocmemset,它分配一個緩衝區,將其設爲零,但你從asctime返回值覆蓋的buf值。當您撥打free時,它的返回值爲asctime,而不是您的原始分配。這有三個問題:

  1. 你從來不會使用你malloc任何有用的目的分配的緩衝區,所以你不需要那麼malloc也不memset
  2. 你失去的指針由malloc所以你永遠不能回來做free它。你的程序泄漏了內存。
  3. 您嘗試free來自asctime的返回值。 asctime的返回值不需要被釋放,也不應該被釋放。這會導致未定義的行爲,在您的情況下是段錯誤。