1

同様の問題について多くのスレッドを検索した後、プログラムでセグ フォールトが発生した理由を特定できませんでした。私は 2 つのファイルを持っています: 循環バッファーを作成し、そこから値をデポジット/削除する 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;
}

バッファ内のセマフォで初めて操作が行われたときにセグフォルトが発生するため、メモリが不適切に割り当てられていると思われますが、その仮定が間違っている場合に備えて、メインのコードを含めました。また、私のコードからは明らかでない場合、私は 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() 関数は実際には何も作成しませんでした。代わりにメモリがリークしただけです。

簡単な修正の 1 つは、main() でメモリを割り当てることです。

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

次の行を削除します。

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

あなたの createSem() がどのように実装されているかわかりません。あなたもチェックしたいかもしれません。

于 2013-10-11T04:38:13.127 に答える