[英]How does strlen(&string[]) work?
這可能是一個很長的問題。 我正在用C測試一些字符數組,因此出現了這段代碼。
char t[10];
strcpy(t, "abcd");
printf("%d\n", strlen(&t[5]));
printf("Length: %d\n", strlen(t));
現在顯然strlen(&t[5])
產生3,而strlen(t)
返回4。
我知道字符串長度為4,這從插入四個字符很明顯。 但是為什么strlen(&t[5])
返回3?
我的猜測是
String: a | b | c | d | 0 | 0 | 0 | 0 | 0 | \0
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
strlen(&t[5])
查看由位置6、7和8組成的字符串的長度(因為第10個字符是NULL終止符,對)?
好的,然后我做了一些實驗,並修改了一些代碼。
char t[10];
strcpy(t, "abcdefghij");
printf("%d\n", strlen(&t[5]));
printf("Length: %d\n", strlen(t));
現在,這一次strlen(&t[5])
產生5,而strlen(t)
為10,正如預期的那樣。 如果我正確理解字符數組,則狀態現在應該為
String: a | b | c | d | e | f | g | h | i | j | '\0'
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
那么為什么strlen(&t[5])
這次返回5? 我已經聲明了一個長度為10的字符數組,那么按照上面應用的相同邏輯,結果應該是4嗎?
另外,由於NULL終止字符實際上位於第11位,我是否也應該遇到一些編譯器錯誤? 我是C語言的新手,非常感謝任何人的幫助。
首先讓我告訴你,你的“假設”
String: a | b | c | d | 0 | 0 | 0 | 0 | 0 | \0
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
是不正確的。 根據您的代碼,僅在“索引4 ”之前“保證”值,而不會超出該值。
對於第一種情況 ,在您的代碼中
printf("%d\n", strlen(&t[5]));
由於各種原因而錯,
%zu
用作size_t
類型。 &t[5]
沒有指向有效的字符串 。 上面的任何一個(或兩個)都會導致未定義的行為,並且任何輸出都無法證明其合理性。
詳盡地定義
char t[10];
strcpy(t, "abcd");
您為t
填充了索引0到3,索引4保留了空終止符。 從t[5]
開始的內容是不確定的。
因此, &t[5]
不是指向字符串第一個元素的指針,因此不能用作strlen()
參數。
確實,兩者都有可能,也有可能。 UB是UB,沒有理由。
然后,對於第二種情況,您說
char t[10];
strcpy(t, "abcdefghij");
再次訪問內存超出范圍。
您總共有10個數組元素來存儲一個字符串,因此您可以有9個其他char
元素以及一個null終止符(將char數組限定為字符串)。
但是,您嘗試放入10個char
元素,再加上一個空字符(在strcpy()
),因此您被一一棄用,訪問綁定內存不足,調用UB。
char t[10];
未初始化,因此僅包含垃圾值1) 。 strcpy(t, "abcd");
用字符串“ abcd”和空終止符覆蓋前5個字符。
但是, &t[5]
指向空終止后的第一個字符,這仍然是垃圾。 如果從那里調用strlen
,則任何事情都可能發生,因為傳遞的指針不太可能指向以null結尾的字符串。
1)垃圾=不確定值。 假設一個理智的2的補碼系統,將使用緩沖區t
的地址,因此直到strlen
開始讀取數組t
的邊界之外的代碼才調用未定義的行為。 參考 。
問題一:
我的猜測是
String: a | b | c | d | 0 | 0 | 0 | 0 | 0 | \\0 Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
這個假設是錯誤的。 數組未初始化為容納0個值,但包含一些“隨機”垃圾。 復制"abcd"
后,數組的上半部分( t[5]
等)仍然未觸及,由於行為不確定,導致字符串的“隨機”長度。
問題2:
如果我正確理解字符數組,則狀態現在應該為
String: a | b | c | d | e | f | g | h | i | j | '\\0' Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
再次錯誤。 您的數組僅包含10個字符。 它們位於索引0..9。 索引10超出范圍。 您的復制操作可能會導致這種布局,或者也可能會在超出范圍時崩潰。
但這不是由編譯器檢查的。 如果您遇到問題,那么它將在運行時。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.