【问题标题】:Unknown segmentation fault likely related to memory allocation可能与内存分配有关的未知分段错误
【发布时间】:2013-10-11 04:20:30
【问题描述】:

在搜索了许多关于类似问题的线程后,我无法确定为什么我的程序会出现段错误。我有两个文件: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 很陌生,所以我很感激任何指导。谢谢!

【问题讨论】:

    标签: c segmentation-fault


    【解决方案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,请注意,在这两种情况下,您都传递了接收结果的变量的地址。前者createBuffer(&bufferA, 128);,后者int n; foo(&n);
    【解决方案2】:

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

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

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

    并删除这一行:

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

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

    【讨论】:

      猜你喜欢
      • 2016-09-29
      • 2021-06-14
      • 2018-11-12
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多