C语言 静态int指针运算导致valgrind无效读取

hyrbngr7  于 2023-04-19  发布在  其他
关注(0)|答案(1)|浏览(151)

我试图创建队列作为双空指针。pollQueue函数用于处理队列并返回队列元素指针dest
我把问题简化成这样:

#include <stdio.h>
#include <stdlib.h>

void **queue;
int queueSize = 0;

int pollQueue(void **dest, int *processPlace);
int processQueue();

int main(void){

    int data = 5;
    
    queue = malloc(sizeof(void *));
    queueSize++;
    *queue = &data;
    
    processQueue();
    
    free(queue);
    
    return 0;
}

int processQueue(){

    void *queueElement = NULL;
    int processPlace = -1;

    while(pollQueue(&queueElement, &processPlace) == 0)
    {        
        //do something with queue element
    };

    return 0;
}

int pollQueue(void **dest, int *processPlace){

    static int processNumber = 0;

    //void *cur = queue[processNumber];
    void *cur = *(queue + processNumber); //0 here

    printf("process number: %i\n", processNumber);

    //if end of the queue reached retun 0 and prepare for next poll
    if(!cur || queueSize == processNumber)
    {
        *processPlace = processNumber;
        dest = NULL;
        processNumber = 0;
        return 1;
    }

    *processPlace = processNumber;
    *dest = cur;

    processNumber++;

    return 0;
}

当我通过valgrind运行这段代码时,我得到了这个:

==14570== Memcheck, a memory error detector
==14570== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14570== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==14570== Command: ./test
==14570== 
process number: 0
==14570== Invalid read of size 8
==14570==    at 0x1092B4: pollQueue (in /home/jan/Documents/programing/c_c++/population/sim/test/test)
==14570==    by 0x10926A: processQueue (in /home/jan/Documents/programing/c_c++/population/sim/test/test)
==14570==    by 0x109202: main (in /home/jan/Documents/programing/c_c++/population/sim/test/test)
==14570==  Address 0x4a96048 is 0 bytes after a block of size 8 alloc'd
==14570==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==14570==    by 0x1091D4: main (in /home/jan/Documents/programing/c_c++/population/sim/test/test)
==14570== 
process number: 1
==14570== 
==14570== HEAP SUMMARY:
==14570==     in use at exit: 0 bytes in 0 blocks
==14570==   total heap usage: 2 allocs, 2 frees, 1,032 bytes allocated
==14570== 
==14570== All heap blocks were freed -- no leaks are possible
==14570== 
==14570== For lists of detected and suppressed errors, rerun with: -s
==14570== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

我不明白是什么导致了错误,我发现更奇怪的是,当我显式地使用0来模拟第一次调用函数时应该发生的事情时,错误消失了。

int pollQueue(void **dest, int *processPlace){

    static int processNumber = 0;

    //void *cur = queue[processNumber];
    void *cur = *(queue + 0); //0 here

    printf("process number: %i\n", processNumber);

    //if end of the queue reached retun 0 and prepare for next poll
    if(!cur || queueSize == processNumber)
    {
        *processPlace = processNumber;
        dest = NULL;
        processNumber = 0;
        return 1;
    }

    *processPlace = processNumber;
    *dest = cur;

    processNumber++;

    return 0;
}

我不能解释为什么使用变量会导致无效的读取,但是当隐式地给出值时,它工作得很好。有人能解释一下吗?

56lgkhnf

56lgkhnf1#

static函数变量的全部意义在于它们在调用之间保持其值。
第一次调用processQueue时,processNumber0开始。在函数退出之前,processNumber递增为1
第二次调用processQueue时,processNumber1开始。由于queue只有一个元素,因此访问*(queue + processNumber)(又名queue[processNumber])会导致未定义的行为。
valgrind正在捕获此严重错误。

相关问题