2013-08-18 157 views
0

下面的代碼在運行時在第二行拋出一個訪問衝突,這在第二次打電話給setword時發生。訪問衝突,memset

Q>我在L2中哪裏出錯了,爲什麼L1行的第一個memset沒有問題?

注意:我試圖從更大的代碼中分離出問題區域,希望能夠提供足夠的信息。

void setword(char ** word) 
{ 
    if (*word == NULL) 
    { 
     *word = (char *)malloc(30); 
     memset(*word, '\0', 30); //L1: OK 
    } 
    else 
    { 
     memset(*word, '\0', 30);//L2: Access violation 
    } 

    *word = "Hello"; 
    //*word shall be freed when operations are complete. 
} 
int main() 
{ 
    char * word = NULL; 

    setword(&word); //Call 1: OK 
    printf("%s\n", word); 

    setword(&word); //Call 2: NOK! 
    printf("%s\n", word); 
} 

回答

5
*word = (char *)malloc(30); 
[...] 
*word = "Hello"; 

第二分配產生了內存泄漏(你已經失去了malloc返回的指針),並使得word點可能只讀存儲器 - 它的任何寫訪問將導致不確定的行爲。

(例如,見這個問題:Is modification of string literals undefined behaviour according to the C89 standard? - 在你的情況,"Hello"是一個字符串字面你讓word點,與第二次分配所以你不能修改數據word點算賬。)

使用strcpy"hello"複製到您的動態分配緩衝區。

+0

我只想補充說,「你好」是程序靜態數據的一部分,可能真的是隻讀內存。 OP很幸運,因爲如果不是,他會覆蓋接下來會發生的事情...... –

+0

非常感謝。在我的原始代碼中,我沒有對* word進行任何處理,實際上我正在使用** word = some_char來填充它。但是,我已經用*詞做了一些指針運算,因爲我已經失去了原來的單詞,導致所有的失敗,就像你指出的那樣! – VivereJay

0

你應該知道*word = "Hello"之後,*word的值是恆定區域,你可以改變這個區域的內容。