[英]Problem of overlap verification between two strings
我目前正在從標准 C 庫重新編碼srtcat()
並且我已經設置了一些檢查以避免重疊問題。 問題是我的程序還是進入了錯誤處理。
這是代碼:
char *my_strcat(char *restrict dest, const char *restrict src)
{
size_t dest_len = 0, src_len = 0;
char *p = dest;
src_len = my_strlen(src);
if (!dest || !src)
return NULL;
dest_len = my_strlen(dest);
if (src >= dest && src < dest + dest_len) {
return NULL;
}
if (dest >= src && dest < src + src_len) {
return NULL;
}
while (*p != '\0') p++, dest_len++;
if (dest_len + src_len + 1 > sizeof(dest))
return NULL;
p = dest + dest_len;
while (*src != '\0')
*p++ = *src++;
*p = '\0';
return dest;
}
size_t my_strlen(const char *s)
{
size_t count = 0;
if (s != NULL) {
while (*s != 0) {
count++;
s++;
}
}
return count;
}
我是這樣測試的:
int main(int argc, char **argv)
{
const char *src = "Hello";
char dest[100] = " world!";
char *test = my_strcat(dest, src);
printf("Src : %s Dest : %s\n", src, dest);
printf("Return adress : %p, Value : %s\n", test, test);
return 0;
}
根據gdb
:
if (src >= dest && src < dest + dest_len)
1: dest = 0x7fffffffda70 " world!"
2: src = 0x555555557004 "Hello"
3: dest_len = 0
4: src_len = 5
Src : Hello Dest : world!
Return adress : (nil), Value : (null)
你看到問題了嗎?
根據您的建議,我修改了如下代碼:
char *my_strcat(char *restrict dest, const char *restrict src, size_t d_size)
{
size_t dest_len = 0, src_len = 0;
char *p = dest;
if (!dest || !src)
return NULL;
src_len = my_strlen(src);
dest_len = my_strlen(dest);
if (src >= dest && src < dest + dest_len) {
return NULL;
}
if (dest >= src && dest < src + src_len) {
return NULL;
}
while (*p != '\0') p++, dest_len++;
if (dest_len + src_len + 1 > d_size)
return NULL;
p = dest + dest_len;
while (*src != '\0')
*p++ = *src++;
*p = '\0';
return dest;
}
主要是: char *test = my_strcat(dest, src, sizeof(dest));
但它仍然不起作用:
Src : Hello Dest : world!
Return adress : 0x7fff74bc5650, Value : world!
在試圖引導理解這個問題之后,最好的辦法似乎是展示什么應該是工作代碼(供研究)。有時太多的詞只會混淆情況:
char *my_strcat(char *restrict dest, const char *restrict src, size_t d_size) {
if( !dest || !src )
return NULL;
size_t src_len = strlen( src );
size_t dest_len = strlen( dest );
if( dest_len + src_len + 1 > d_size )
return NULL;
char *p = dest + dest_len;
while( (*p++ = *src++ ) != '\0' )
;
return dest;
}
int main() {
const char *src = "Hello";
char dest[100] = " world!";
printf("Src : %s Dest : %s\n", src, dest);
char *test = my_strcat( dest, src, sizeof dest );
if( test )
printf("Value : %s\n", test );
return 0;
}
現在,可以通過將dest
的大小縮小到大於“world”的大小來進行實驗。 但比“world.Hello”小?? 也許 9 個字節???
而且,既然串聯應該起作用(進入足夠大的緩沖區),添加代碼以確保實際字符 arrays 沒有重疊。已知 dest 的大小,並測量 src 的長度。
dest_len + src_len + 1 > sizeof(dest)
sizeof(dest)
是指針sizeof(char*)
的大小。 如果你想檢查dest
是否會溢出,你必須將大小作為參數傳遞。 請參閱strlcpy
或strncpy
。
src >= dest
請注意,比較不指向同一數組的指針在技術上是無效的。 為了帶來一些有效性,您可以執行(uintptr_t)stc >= (uintptr_t)dest
。 指針比較在 C 中如何工作? 可以比較不指向同一個數組的指針嗎? 如果兩個指針都被強制轉換為 integer 類型,是否正在比較具有 < undefined 行為的指針? 為什么比較具有未定義行為的指針仍會給出正確的結果? 等等
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.