[英]Can someone explain to me why this is possible?
int main ()
{
char *strA = "abc";
int tam_strA = strlen(strA);
char strB[tam_strA];
strB[0] = 'a';
strB[1] = 'b';
strB[2] = 'c';
strB[3] = 'd';
strB[9] = 'z';
printf("%c", strB[9]);
return 0;
}
它正常打印'z'。 為什么它不返回分段錯誤錯誤? 因為我試圖訪問一個不應該存在的索引,因為 strB 的大小(索引數量)等於等於 3 的 tam_strA。
另外,做char strB[strlen(strA)];
有什么不同/問題嗎? 反而?
C 語言沒有阻止您訪問無效 memory 的規范,也不保證分段錯誤。 唯一的 promise 是,如果您嘗試訪問無效的 memory,這將導致未定義的行為。
分段錯誤是可能的結果之一,而不是唯一的結果。
也就是說,唯一的問題是
char strB[strlen(strA)];
也就是說, strB
的長度不足以保存strA
中的內容,因為它將缺少一個字節來保存空終止符。 當然,按字節使用就可以了,但是如果您想復制內容(或與strA
長度相同的任何內容)並將strB
用作string ,您將跑過分配的 memory (沒有 null終止符),調用未定義的行為。
訪問不屬於您的 memory 時,您只會遇到分段錯誤。 你擁有你的整個堆棧。 strB[9]
在操作系統看來是一個有效的 memory 訪問。 您不應該這樣做的原因是因為編譯器不知道您使用的是 memory,因此它可能決定將 memory 用於其他用途。 它還有助於提高可讀性並最大限度地減少程序員的錯誤。 而且,該標准將未聲明的 memory 的使用定義為未定義的行為,因此您不能安全地使用它。 聲明一個像int x;
(或數組)告訴編譯器您將在x
處使用 memory。
這實際上與這個問題有關: 為什么定義數組之外的第一個元素默認為零? . 閱讀那里更詳細的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.