Sunday, January 17, 2010

string.h里的函数的maxlen限制

maxlen是指最大长度。 第一次注意到maxlen这个参数是在:
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
optimizemaxlen
optimizeinformation
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.

strcasestrYes



length






strlen
Yes
strnlen
Yes

compare






strcmp
No
strncmp
Yes




memcmpYes


strcasecmpNo
strncaseNo







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.