Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Valgrind:无效的读取(&A);单位价值的使用_C_Segmentation Fault_Valgrind - Fatal编程技术网

C Valgrind:无效的读取(&A);单位价值的使用

C Valgrind:无效的读取(&A);单位价值的使用,c,segmentation-fault,valgrind,C,Segmentation Fault,Valgrind,我试图实现一个基本的循环缓冲区,然后在该缓冲区中生成/使用几个字符。由于多个线程将访问同一个缓冲区,因此我还使用信号量来防止并发访问。我的程序编译和运行正常,但一旦我给它传递了一个字符,它就会导致分割错误。我一直在尝试使用Valgrind进行调试,但除了错误存在于我的缓冲区代码中这一事实之外,我还无法从中获得更多的用途,如下所示: [...]//headers void createBuffer(Buffer *buff, int buffSize){ buff = (Buffe

我试图实现一个基本的循环缓冲区,然后在该缓冲区中生成/使用几个字符。由于多个线程将访问同一个缓冲区,因此我还使用信号量来防止并发访问。我的程序编译和运行正常,但一旦我给它传递了一个字符,它就会导致分割错误。我一直在尝试使用Valgrind进行调试,但除了错误存在于我的缓冲区代码中这一事实之外,我还无法从中获得更多的用途,如下所示:

[...]//headers
void createBuffer(Buffer *buff, int buffSize){
        buff = (Buffer*) calloc(1, sizeof(Buffer));
        semaphore mutex,emptyBuffers,fullBuffers;
        createSem(&mutex, 1);
        createSem(&emptyBuffers,buffSize);
        createSem(&fullBuffers,0);
        (buff->mutex) = &mutex;
        (buff->emptyBuffers) = &emptyBuffers;
        (buff->fullBuffers) = &fullBuffers;
        buff->charBuff = malloc(sizeof(char) * buffSize);
        buff->nextIn = 0;
        buff->nextOut = 0;
        buff->buffSize = buffSize;
}
void deposit(char in, Buffer *buffer) {
        down(buffer->emptyBuffers);    //line 20 in buffer.c
        (buffer->charBuff)[buffer->nextIn] = in;
        buffer->nextIn = (buffer->nextIn + 1) % buffer->buffSize;
        up(buffer->fullBuffers);
}
[...]//remove function
之后的remove函数类似于deposit(),因此,如果需要的话,弄清楚如何修复一个就足够了。以下是Valgrind的输出:

==10846== Use of uninitialised value of size 8
==10846==    at 0x4014EF: deposit (buffer.c:20)
==10846==    by 0x40124F: getInputStream (test.c:80)
==10846==    by 0x401C55: _st_thread_main (in a.out)
==10846==    by 0x401D1D: st_thread_create (in a.out)
==10846== 
==10846== Invalid read of size 4
==10846==    at 0x40167A: down (in a.out)
==10846==    by 0x4014FA: deposit (buffer.c:20)
==10846==    by 0x40124F: getInputStream (test.c:80)
==10846==    by 0x401C55: _st_thread_main (in a.out)
==10846==    by 0x401D1D: st_thread_create (in a.out)
==10846==  Address 0xc74800405020c0c7 is not stack'd, malloc'd or (recently) free'd
==10846== 
==10846== Process terminating with default action of signal 11 (SIGSEGV)
==10846==  General Protection Fault
==10846==    at 0x40167A: down (in a.out)
==10846==    by 0x4014FA: deposit (buffer.c:20)
==10846==    by 0x40124F: getInputStream (test.c:80)
==10846==    by 0x401C55: _st_thread_main (in a.out)
==10846==    by 0x401D1D: st_thread_create (in a.out)
我对Valgrind很陌生(而且只是一个C新手),所以我一直在寻找其他具有类似Valgrind输出的人,但是我没有找到任何有用的东西

最后的几条注释(抱歉这么长!):这是给学校的,所以如果可能的话,我更喜欢指导而不是代码。此外,尽管Valgrind输出确实提到了“无效读取”和down函数之间的连接,但我可以确认down函数——以及信号量类型本身——能够正常运行。最后,我在初始化缓冲区和在createBuffer()中分配内存时遇到了一些困难;结合seg故障的性质,如果错误与该函数有关,我不会感到惊讶,尽管Valgrind没有引用它

TL;DR:Seg程序中的错误,作为Valgrind的新手和C语言的相当缺乏经验的人,我很难理解。上面的代码。谢谢

编辑:由于下面给出的有用建议而意识到我的错误后,我在尝试为信号量分配内存以防止其丢失时遇到了另一个seg错误。我试过几种方法,每种都有相同的结果。我的新尝试如下:

buff->mutex = calloc(1,sizeof(semaphore));
buff->mutex = &mutex;


与我的第一个问题一样,当信号量首次在createBuffer(…)外部引用时,这些仍然会导致分段错误。

您使用的是指向局部变量的指针。函数返回后,这些变量使用过的空间将被回收并重新用于下一次函数调用


请记住,局部变量的生存期仅在定义该变量的函数中。

您的信号量不能是
createBuffer()中的局部变量。
;它们必须持续到你破坏缓冲区为止。要么动态分配,要么使用静态分配的变量。啊,当然!我早就这么做了,一定是在乱写代码时删除了它们。谢谢你!我现在明白了为什么我从一开始就删除了这段代码——我无法正确地实现它。我试着用几种方法为信号量分配内存,并且每种方法都有一个seg错误。对我来说最有意义的方法是在每个buff->semaphore上使用calloc(),然后分配*(buff->semaphore)=*semaphore,这和其他方法一样不起作用。@user2848583如果
buff->semaphore
是一个指针,你不能在不使指针实际指向某个对象的情况下使用取消引用操作符(
*
)。只需执行例如
buff->semaphore=calloc(…)。请记住,您必须
释放该指针。非常感谢您的持续指导。如果我理解正确,我尝试了您的建议(如有必要,请参阅上面的编辑代码),但仍然导致seg故障。你能指出我的误解吗?另外,释放分配的内存不会在显示的代码中完成,而是在我的主程序结束时,我不再需要访问信号量,对吗?
buff->mutex = calloc(1,sizeof(semaphore));
createSem(buff->mutex,1);
//I removed the previous semaphore declarations and calls to createSem(...)