c -静态int指针算术导致valgrind无效读取



我试图创建队列作为双void指针。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: %in", 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: %in", 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;
}

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

static函数变量的全部意义在于它们在调用之间保持其值。

第一次调用processQueue时,processNumber0开始。在函数退出前,processNumber被加为1

第二次调用processQueue时,processNumber开始为1。由于queue只有一个元素,访问*(queue + processNumber)也就是queue[processNumber]会导致未定义的行为。

valgrind正在捕获这个严重的错误。

相关内容

  • 没有找到相关文章

最新更新