2015-09-21 14 views
0

減少。考慮下面的一段代碼。該函數從文件讀取一些整數和字符串。奇怪的是,循環計數器變量被.get()

const int vardo_ilgis = 10; 
void skaityti(int &n, int &m, int &tiriama, avys A[]) 
{ 
    ifstream fd("test.txt"); 
    fd >> n >> m >> tiriama; 
    fd.ignore(80, '\n'); 
    char vard[vardo_ilgis]; // <--- 
    for(int i = 1; i <= n; i++) 
    { 
     cout << i << ' '; 
     fd.get(vard, vardo_ilgis+1); // <--- 
     cout << i << endl; 
     A[i].vardas = vard; 
     getline(fd, A[i].DNR); 
    } 
    fd.close(); 
} 

和輸入:

4 6 
4 
Baltukas TAGCTT 
Bailioji ATGCAA 
Doli  AGGCTC 
Smarkuolis AATGAA 

在這種情況下,變量 'vard' 具有長度vardo_ilgis = 10,但在功能fd.get讀出輸入是vardo_ilgis + 1 = 11(大於數據存儲的可變長度)。我並沒有問如何解決一個問題,因爲很明顯,不能讀取比存儲在變量上更多的內容。 但是,我真的很想理解這種行爲的原因:循環計數變量被fd.get減少。爲什麼以及如何發生這種情況?這是這段代碼的輸出:

1 0 
1 0 
1 0 
1 0 
1 1 
2 2 
3 3 
4 4 
+0

這是哪一語言?聽起來像高Valyrian – TemplateRex

回答

0

你爲什麼用+1

fd.get(vard, vardo_ilgis+1); 

超出緩衝區會破壞某些內存。在一個簡單的未經優化的版本中,損壞的內存可能是循環索引。

循環計數變量被fd.get減少。爲什麼以及如何發生這種情況?

一旦你知道你爲什麼導致了未定義的行爲,許多人說你不應該詢問那些未定義的行爲的細節。我不同意。通過了解細節,您可以提高診斷其他情況的能力,在這些情況下,您不知道您可能調用了哪些未定義的行爲。

你所有的本地變量都存儲在一起,因此覆蓋一個會傾向於打斷另一個。

您描述的變量被「減少」,實際上它被設置爲零。在被歸零之前它是1的事實並不影響其被歸零。未定義的行爲恰好相當於i&=~255;,對於256以下的值等於i=0;。這是更偶然的,你可以看到它作爲i--;

希望很清楚爲什麼i停止被歸零後,一旦你用完輸入。

0

fd.get(vard, vardo_ilgis+1);使緩衝區被寫出界限。

就你而言,你寫的地方(以及你不應該在的地方)可能是存儲i的地方。

但是,最重要的是你最終會遇到如此着名的未確定行爲。這意味着任何事情都可能發生,試圖理解爲什麼或如何發生(發生什麼是平臺,編譯器甚至上下文特定,我認爲任何人都不能預測或解釋它)是沒有意義的。