size_t __strnlen (const char *str, size_t maxlen)
C里, 对内存的操作常常是一个循环, 针对于字符串的话, 循环的退出条件常常是: 一个特定的字符
1. 如'\0'
2. strchr的第二个参数
这样, 在历遍这块内存时, 需要程序员明白一点: 自己是否确认1和2的字符串在你操作的内存中?
否则, 这将是很危险的. 举个例子:
void main(int argc, char *argv){
char a[10], b[10];
memset(a, 'b', 10);
a[5] = '\0';
//这里证明a的址址比b的高
printf("a - b = %d\n", (int)(a - b));
//b长度就会有问题
printf("strlen(a): %d, strlen(b): %d\n", strlen(a), strlen(b));
//应该使用strnlen函数!, strlen和strnlen的区别就在于maxlen
printf("strnlen(a): %d, strnlen(b): %d\n", strnlen(a, sizeof(a)), strnlen(b, sizeof(b)));
}
输出:
a - b = 10
strlen(a): 5, strlen(b): 15
strnlen(a): 5, strnlen(b): 10
如果在使用strlen的同时, 使用memset函数, 将会是灾难性的
按照这一种考虑, 把glibc/string下的函数分成如下
no maxlen | optimize | maxlen | optimize | information | |
copy | |||||
strcpy | No | strncpy | Yes | strncpy(s1, s2, maxlen) 如果maxlen > strlen(s2), 那么 剩下的都用'\0'填充. 使用strcpy最后一个也为'\0' | |
memset | Yes | ||||
memcpy | Yes | ||||
memccpy | No | memccpy(dest, src, '\0', maxlen)与strncp差不多,但是最后只有一个'\0' | |||
mempcpy | Yes | 与memcpy相似 | |||
duplicate | |||||
strdup | Yes | strndup | 两者的区别是 调用strlen或者 调用strnlen 最后都调用 memcpy 最后byte为'\0' | ||
find | |||||
strchr | Yes | memchr | Yes | ||
strrchr | Yes | memrchr | Yes | strrchr调用strchr | |
strchrnull | Yes | ||||
strstr | Yes | memmem | Yes | using a linear algorithm with a smaller coefficient. | |
strcasestr | Yes | ||||
length | |||||
strlen | Yes | strnlen | Yes | ||
compare | |||||
strcmp | No | strncmp | Yes | ||
memcmp | Yes | ||||
strcasecmp | No | strncase | No | ||
concatenate | |||||
strcat | No | strncat | Yes | ||
move | |||||
memmove | |||||
set | |||||
strspn | |||||
strcspn | |||||
other | |||||
strfry | |||||
strxfrm |
* optimize的意思是被多个字节一起操作, 或者可以被compiler优化
PS:: 为了安全, 还是有mexlen参数的函数靠谱, 再者, 有maxlen的函数会快
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.