簡體   English   中英

strlen(&string [])如何工作?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM