代码之家  ›  专栏  ›  技术社区  ›  river

怎么可能(-1>=sizeof(buffer))是真的程序无法获得正确的比较结果

  •  1
  • river  · 技术社区  · 6 年前

    程序运行到不可能的执行例程,其中 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 ......
    

    我认为这个虫子是由烟囱污染引起的,但很难找出它的秘密更重要的是,我列出了函数的代码 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 回复  |  直到 6 年前
        1
  •  3
  •   chux    6 年前

    -1,大于sizeof(buff)太神奇了。

    它是。

    len >= sizeof(buff) -1 >= sizeof(buff) 等同于 (size_t)-1 >= sizeof(buff) --> SIZE_MAX >= sizeof(buff) --&这当然是真的。

    int 喜欢 len 未签名 类型 size_t ,结果是 sizeof ,其中一种类型将转换为另一种类型,在此基础上具有更大的范围。

    在这种情况下,通常是 内景 转换为 未签名 西泽特 . (size_t)-1 是最大的价值 尺寸 而且肯定比 sizeof(buff) .


    现在还不清楚为什么 len == -1 没有看到更多的代码。

    但在这种情况下,我建议使用 size_t len = 0 修正代码。


    打印时,使用匹配的打印说明符,如 "%zu"

    printf("size:%zu\n", sizeof buff);
    

    操作代码,没有警告 printf("%d\n", sizeof(buff)); 表示警告未完全启用节省时间启用所有警告。