2012-04-30 24 views
1

考慮下面的代碼:訪問衝突寫入靜態全局變量?

#include "stdafx.h" 
#include "string.h" 
static char *myStaticArray[] = {"HelloOne", "Two", "Three"}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char * p = strstr(myStaticArray[0],"One"); 
    char hello[10]; 
    memset(hello,0,sizeof(hello)); 
    strncpy(hello,"Hello",6); 
    strncpy(p,"Hello",3); // Access Violation 
    return 0; 
} 

我正好在點得到一個訪問衝突,當它試圖寫入myStaticArray的地址[0]。 爲什麼這是一個問題?

背景:我移植舊的C++到C#,主要是一個C#開發人員,所以請原諒我的無知!這段代碼顯然是不能在舊的生成問題,所以我很困惑...

+3

這不是C++。它基本上是C,與良好的C++代碼根本沒有任何關係。 – Puppy

回答

5
char * p = strstr(myStaticArray[0],"One"); 

p指向字符串「HelloOne」的一部分。您不得嘗試修改字符串文字,這是未定義的行爲。

通常,字符串存儲在只讀存儲器的一部分,所以想對其進行寫操作會導致分割故障/訪問衝突。

+0

簡單的答案,我懷疑,感謝您的快速反應。這是否曾經允許在一個更古老的編譯器下? – Riken

+1

@Riken:它似乎可以在一些較老的編譯器上工作,但它一直是未定義的行爲。 – ildjarn

+0

@Riken字符串文字可以修改爲C擴展名,所以在某些實現中可以修改。 – ouah

2
static char *myStaticArray[] = {"HelloOne", "Two", "Three"}; 

數組中的字符串是字符串文字,並且在C和C++中是不可修改的。

strncpy(p,"Hello",3); 

此函數調用嘗試修改字符串文字。

另一個問題是你的strncpy函數並不總是空終止字符串的使用。這是這裏的情況,因爲strlen("Hello")大於3(你最後strncpy參數)。

0

如果你希望能夠修改字符串,那麼你就需要分配的字符數組這樣

static char myStaticArray[][25] = {"HelloOne", "two", "three"}; 

的問題,因爲別人說是你的方法使編譯器創建的數組指向常量字符串的3個指針。上面的聲明創建了一個兩個dementional字符數組,然後將常量字符串數據複製到該內存。