1

在搜索了许多关于类似问题的线程后,我无法确定为什么我的程序出现了段错误。我有两个文件: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);
}

和缓冲区.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 很陌生,所以我很感激任何指导。谢谢!

4

2 回答 2

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
}

calloc/malloc同样在 C 中,只有在使用 C++ 编译器进行编译时,您才不会转换返回的内容,但是您应该new改用

于 2013-10-11T04:39:27.537 回答
0

在 c 中,函数参数是按值传递的,因此您的 createBuffer() 函数并没有真正创建任何东西;它只是泄漏了内存。

一个简单的解决方法是在 main() 中分配内存:

  bufferA  = (Buffer*) calloc(1, sizeof(Buffer));

并删除这一行:

  buff = (Buffer*) calloc(1, sizeof(Buffer));

我看不到您的 createSem() 是如何实现的,您可能也想检查一下。

于 2013-10-11T04:38:13.127 回答