2016-12-01 217 views
1

我不明白爲什麼這段代碼拋出未處理的「訪問衝突」異常。這是一個簡單的程序,試圖將一個字符指針字符串複製到另一個時(索引字符:3,4,5)跳過某些字符字符指針拋出訪問衝突

#include <conio.h> 
#include <iostream> 
using namespace std; 


void main() 
{ 
char str[20]; 
char *str1 = "abcdeabcde", *str2 = ""; 
int i, dx = 0; 

for(i=0; *(str1+i)!='\0'; i++) 
    if(i<3 || i>5) 
    { 
     *(str2 + dx) = *(str1 + i); 
     dx++; 
    } 
*(str2+dx) = '\0'; 
cout<<str2; 

_getch(); 
} 

儘管分配使用語法*(str + i)下面的函數代碼工作正常(它是一個getline的實現)

int getstr(char *str, int n) 
{ 
    char ch; 
    int i = 0; 
    for(i=0; i<n && (ch = _getch())!= '\r'; i++) 
    { 
     if(ch == '\b') 
     { 
      if(i == 0) 
      { 
       i = -1; continue; 
      } 
      else 
      { 
       cout<<"\b \b"; 
       i -= 2; 
      } 
     } 
     else if(ch > 31 && ch < 127 && i<n-1) 
     { 
      cout<<ch; 
      *(str + i) = ch; 
     } 
     else 
     { 
      cout<<"\a"; 
      i--; 
     } 
    } 
    *(str + i) = '\0'; 
    return i+1; 
} 

那麼,爲什麼這在第二種情況下,但不是在第一個?

+0

'std :: string newstr(oldstr); newstr.erase(3,3);'如果你沒有被STL資產禁止,就幹這個工作。 –

+0

如果你使用的是標準兼容編譯器,它會告訴你,char * str1 =「abcdeabcde」,* str2 =「」'是不合格的。 – user2079303

回答

3

那麼,爲什麼這在第二種情況下,但不是在第一個?

因爲在第一種情況下,這些是文字字符串char *str1 = "abcdeabcde", *str2 = "";和你正在不允許改變的任str1str2

內容這是在C/C的公知未定義行爲++。看到這份名單:What are all the common undefined behaviours that a C++ programmer should know about?

尤其在該行

  • 試圖在其一生中修改字符串文字或任何其他const對象(UB)
+0

Dôh!你打了我一秒。 – YSC

2

就出在這裏你的問題:

*(str2 + dx) = *(str1 + i); 

str2是一個指向字符串文字的指針。只要你沒有讀過它的NUL字符,但你不允許寫它,你可以從str2中讀取,因爲編譯器可能會將字符串字面值存儲在二進制文件的特定和只讀部分。

在這裏,你寫信給str2過去它的結束。這是一個雙重未定義的行爲!