想象一下,有了這段代碼,除了 char 指標(字串終止或字符陣列(字串未終止))之外,您真的不知道要做什么,可以以安全的方式使用 strlen 函式來處理未終止的字串? (如果輸入不是以字串結尾的,則防止溢位)還是只能通過知道傳入輸入的內容的大小來修復它?所以函式會變成foo(char *c, size_t MAXSIZE)?
void foo(char *c) {
a = strlen(c);
}
uj5u.com熱心網友回復:
我們永遠不知道指標背后的真正含義。它也只能是指向單個字符的指標。即使傳遞一個大小,你也可以想象有人傳遞了一個錯誤的指標和一個不相關的值。
C 不是一種安全語言,它沒有運行時型別檢查。你可以做任何你想做的事情,你不能阻止其他人用你的功能做任何他們想做的事情。
uj5u.com熱心網友回復:
strlen如果它不是以空字符結尾的位元組字串,則使用它是不安全的。根據cppreference:
如果 str 不是指向空終止位元組字串的指標,則行為未定義。
如果您想涵蓋非空終止位元組字串的情況,那么您應該使用size_t strnlen_s( const char *str, size_t strsz ),它的作業方式與正常strlen情況一樣,但有例外:
如果 str 是空指標,則函式回傳零,如果在 str 的第一個 strsz 位元組中找不到空字符,則回傳 strsz。
uj5u.com熱心網友回復:
除非您通過大小,否則這是不可能的。
您可避免崩潰,至少-通過詢問作業系統多可讀存盤器有如何在這個地址。(Windows:呼叫 VirtualQuery。Linux:讀取 /proc/self/maps)。但它沒有幫助。在您的字串之后可能有很多與您的字串完全無關的可讀記憶體,但恰好在它之后被分配。找出多少記憶體可以安全讀取并不能告訴您字串有多長。
uj5u.com熱心網友回復:
要檢查緩沖區是否在最大字符數內包含空終止符,memchr可以使用該函式。以下函式的safe_strlen行為類似于strlen_sC 規范的 Annex K 定義的函式,memchr用于查找緩沖區中第一個(如果有)空終止符的位置。
#include <stdint.h>
#include <string.h>
/**
* Get the length of a possibly null terminated string, clamped to a maximum.
*
* If \p s is not NULL, searches up to \p maxsize bytes from \p s to find the
* first null terminator, if any.
*
* \param s Start of string.
* \param maxsize Maximum number of bytes to search.
*
* \return 0 if \p s is \c NULL.
* \return \p maxsize if null terminator not found.
* \return length of null terminated string if null terminator found.
*/
size_t safe_strlen(const char *s, size_t maxsize)
{
size_t length = 0;
if (s)
{
#if PTRDIFF_MAX < SIZE_MAX
/* May need to search the buffer in chunks. */
while (maxsize)
#endif
{
const char *e;
size_t pos;
#if PTRDIFF_MAX < SIZE_MAX
if (maxsize > PTRDIFF_MAX)
{
/* Limit size of chunk. */
pos = PTRDIFF_MAX;
}
else
#endif
{
/* This is the final chunk. */
pos = maxsize;
}
/* Search for null terminator in chunk. */
e = memchr(s, 0, pos);
if (e) {
/* Null terminator found. */
pos = e - s; /* position of null terminator in chunk */
#if PTRDIFF_MAX < SIZE_MAX
/* Make this the final chunk. */
maxsize = pos;
#endif
}
/* Update returned length. */
length = pos;
#if PTRDIFF_MAX < SIZE_MAX
/* Advance to next chunk. */
s = pos;
maxsize -= pos;
#endif
}
}
return length;
}
由于需要處理大于PTRDIFF_MAXifPTRDIFF_MAX小于 的緩沖區大小,代碼變得復雜SIZE_MAX。沒有額外安全檢查的核心功能如下:
/* less safe version of the above - may result in undefined behavior. */
size_t less_safe_strlen(const char *s, size_t maxsize)
{
size_t length = 0;
if (s)
{
const char *e = memchr(s, 0, maxsize);
if (e)
{
length = e - s;
}
else
{
length = maxsize;
}
}
return length;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/338869.html
下一篇:堆疊結構與堆結構有什么區別?
