(-1 >= sizeof(buffer)) 怎么可能是真的?程序无法获得正确的比较结果
How can (-1 >= sizeof(buffer)) ever be true? Program fail to get right results of comparison
程序遇到了不可能执行的例程,其中if( len >= sizeof(buff) )
在现实中永远不应该是真的,但它确实发生了。如printf
输出len:-1__1024
所示:len
,其值为-1,大于sizeof(buff)
,即1024。很神奇。
select return value -1 ,4
select: Interrupted system call
-1_0x66a1e0
len:-1__1024
*** glibc detected *** /home/fang/Desktop/work/fw: free(): invalid pointer: 0x000000000066a1e0 ***
下面是执行代码
while (1) {
if( len >= sizeof(buff) ) { //here len==-1, sizeof(buff)==1024
printf("len:%d__%d %s\n", len, sizeof(buff), tmp1); //oops
free(tmp1);
tmp1 = buff;
}
len = get_next_event(&tmp1, sizeof(buff));
printf("%d_%p\n",len, tmp1);
if( len > 0 ){
tmp = strtok_r(tmp1, "\n\r", &saveptr);
// ignore following codes ......
我认为这个bug是由于堆栈污染造成的,但很难找出其中的秘密。多提一下,我列出了函数的代码get_next_event
。希望得到您的帮助^_^
int get_next_event(char **buf, int len)
{
struct timeval tv;
int tmp;
socklen_t sin_size;
struct sockaddr_in client_addr;
sin_size = sizeof(client_addr);
FD_ZERO(&fdsr);
FD_SET(sock_fd, &fdsr);
tv.tv_sec = 1;
tv.tv_usec = 0;
if (new_fd != 0) {
FD_SET(new_fd, &fdsr);
}
tmp = select(maxsock + 1, &fdsr, NULL, NULL, &tv);
if (tmp < 0) {
printf("select return value %d ,%d\n", tmp, errno);
perror("select");
return -1;
} else if (tmp == 0) {
return 0;
}
-1, is larger than sizeof(buff). It's amazing.
是。
len >= sizeof(buff)
等同于 -1 >= sizeof(buff)
等同于 (size_t)-1 >= sizeof(buff)
--> SIZE_MAX >= sizeof(buff)
--> 确实如此。
当 int
如 len
与 unsigned 类型 size_t
比较时,sizeof
的结果,一个类型转换为其他类型,范围更广。
在这种情况下,通常是int
转换为unsignedsize_t
。 (size_t)-1
是size_t
的最大值,肯定大于sizeof(buff)
。
不清楚为什么 len == -1
没有看到更多代码。
但在这种情况下,我建议使用 size_t len = 0
来修改代码。
打印时,使用匹配的打印说明符,如 "%zu"
printf("size:%zu\n", sizeof buff);
OP 的代码,缺少警告,printf("%d\n", sizeof(buff));
表示警告未完全启用。省时间。启用所有警告。
程序遇到了不可能执行的例程,其中if( len >= sizeof(buff) )
在现实中永远不应该是真的,但它确实发生了。如printf
输出len:-1__1024
所示:len
,其值为-1,大于sizeof(buff)
,即1024。很神奇。
select return value -1 ,4
select: Interrupted system call
-1_0x66a1e0
len:-1__1024
*** glibc detected *** /home/fang/Desktop/work/fw: free(): invalid pointer: 0x000000000066a1e0 ***
下面是执行代码
while (1) {
if( len >= sizeof(buff) ) { //here len==-1, sizeof(buff)==1024
printf("len:%d__%d %s\n", len, sizeof(buff), tmp1); //oops
free(tmp1);
tmp1 = buff;
}
len = get_next_event(&tmp1, sizeof(buff));
printf("%d_%p\n",len, tmp1);
if( len > 0 ){
tmp = strtok_r(tmp1, "\n\r", &saveptr);
// ignore following codes ......
我认为这个bug是由于堆栈污染造成的,但很难找出其中的秘密。多提一下,我列出了函数的代码get_next_event
。希望得到您的帮助^_^
int get_next_event(char **buf, int len)
{
struct timeval tv;
int tmp;
socklen_t sin_size;
struct sockaddr_in client_addr;
sin_size = sizeof(client_addr);
FD_ZERO(&fdsr);
FD_SET(sock_fd, &fdsr);
tv.tv_sec = 1;
tv.tv_usec = 0;
if (new_fd != 0) {
FD_SET(new_fd, &fdsr);
}
tmp = select(maxsock + 1, &fdsr, NULL, NULL, &tv);
if (tmp < 0) {
printf("select return value %d ,%d\n", tmp, errno);
perror("select");
return -1;
} else if (tmp == 0) {
return 0;
}
-1, is larger than sizeof(buff). It's amazing.
是。
len >= sizeof(buff)
等同于 -1 >= sizeof(buff)
等同于 (size_t)-1 >= sizeof(buff)
--> SIZE_MAX >= sizeof(buff)
--> 确实如此。
当 int
如 len
与 unsigned 类型 size_t
比较时,sizeof
的结果,一个类型转换为其他类型,范围更广。
在这种情况下,通常是int
转换为unsignedsize_t
。 (size_t)-1
是size_t
的最大值,肯定大于sizeof(buff)
。
不清楚为什么 len == -1
没有看到更多代码。
但在这种情况下,我建议使用 size_t len = 0
来修改代码。
打印时,使用匹配的打印说明符,如 "%zu"
printf("size:%zu\n", sizeof buff);
OP 的代码,缺少警告,printf("%d\n", sizeof(buff));
表示警告未完全启用。省时间。启用所有警告。