在搜索了类似问题的许多主题之后,我一直无法确定为什么我的程序出现了错误。我有两个文件:buffer.c,我创建一个循环缓冲区并从中存入/删除值和一个主文件,其中多个线程使用用户输入调用循环缓冲区上的操作。信号量用于防止并发访问。
以下是我主程序的相关部分:
int main (int argc, char const *argv[]) {
st_init();
Buffer *bufferA,*bufferB,*bufferC;
createBuffer(bufferA,128);
createBuffer(bufferB,128);
createBuffer(bufferC,128);
// Create the struct used to initialize threads.
ThreadInit initA = {
bufferA,
bufferA
};
ThreadInit initB = {
bufferA,
bufferB
};
ThreadInit initC = {
bufferB,
bufferC
};
ThreadInit initD = {
bufferC,
bufferC
};
// Create threads
if (st_thread_create(getInputStream, &initA, 0, 0) == NULL) {
perror("Thread a creation failure.");
exit(EXIT_FAILURE);
}
if (st_thread_create(convertCR, &initB, 0, 0) == NULL) {
perror("Thread b creation failure.");
exit(EXIT_FAILURE);
}
if (st_thread_create(squashChar, &initC, 0, 0) == NULL) {
perror("Thread c creation failure.");
exit(EXIT_FAILURE);
}
if (st_thread_create(printOutput, &initD, 0, 0) == NULL) {
perror("Thread d creation failure.");
exit(EXIT_FAILURE);
}
// Exit from main via ST.
st_thread_exit(NULL);
return 0;
}
void *getInputStream(void *state) {
ThreadInit *threadInit = state;
char inputChar = getchar();
while (inputChar != EOF) {
deposit(inputChar, threadInit->produceBuff); //where segfault occurs
inputChar = getchar();
st_usleep(SLEEP_TIME);
}
st_thread_exit(NULL);
}
和buffer.c
void createBuffer(Buffer *buff, int buffSize){
buff = (Buffer*) calloc(1, sizeof(Buffer));
semaphore mutex,emptyBuffers,fullBuffers;
buff->mutex = calloc(1,sizeof(semaphore));
buff->emptyBuffers = calloc(1,sizeof(semaphore));
buff->fullBuffers = calloc(1,sizeof(semaphore));
createSem(buff->mutex,1);
createSem(buff->emptyBuffers,buffSize);
createSem(buff->fullBuffers,0);
buff->charBuff = malloc(sizeof(char) * buffSize);
buff->nextIn = 0;
buff->nextOut = 0;
buff->buffSize = buffSize;
}
第一次对我的缓冲区中的信号量进行操作时会出现seg错误,这导致我相信它们的内存分配不正确,尽管我包含了来自main的代码,以防我在这个假设中出错。另外,如果我的代码不清楚,我对C很新,所以我很感激任何指导。谢谢!
答案 0 :(得分:1)
这是错误
void createBuffer(Buffer *buff, int buffSize){
buff = (Buffer*) calloc(1, sizeof(Buffer));
您需要返回缓冲区的指针,否则您不会将更改的指针返回给调用者
void createBuffer(Buffer **buff, int buffSize){
*buff = calloc(1, sizeof(Buffer));
有点简化:它类似于
int foo(int a)
{
a = 1; // 1 not visible outside foo
}
和
int foo(int *a)
{
*a = 1; // 1 is visible outside foo
}
同样在C中,只有在使用C ++编译器进行编译时才会转换从calloc/malloc
返回的内容,但是你应该使用new
而不是
答案 1 :(得分:0)
在c中,函数参数是按值传递的,因此你的createBuffer()函数并没有真正创建任何东西;它只是泄露了记忆。
一个简单的解决方法是在main()中分配内存:
bufferA = (Buffer*) calloc(1, sizeof(Buffer));
并删除此行:
buff = (Buffer*) calloc(1, sizeof(Buffer));
我不知道你的createSem()是如何实现的,你可能也想检查它。