简体   繁体   中英

Unknown segmentation fault likely related to memory allocation

After searching through many threads on similar issues, I've been unable to determine why I've been getting a seg fault with my program. I have two files: buffer.c where I create a circular buffer and deposit/remove values from it and a main file where several threads call the operations on the circular buffer with user input. Semaphores are used to prevent concurrent access.

Here are the relevant parts of my main program:

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);
}

and 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;
}

The seg fault occurs the first time an operation is done on the semaphores in my buffers, which leads me to believe their memory is improperly allocated, though I included the code from my main in case I'm wrong in that assumption. Also, in case it's not clear from my code, I'm quite new to C, so I'd appreciate any guidance. Thanks!

Here is the error

void createBuffer(Buffer *buff, int buffSize){
        buff = (Buffer*) calloc(1, sizeof(Buffer));

you need to return the pointer of the buffer otherwise you are not returning the changed pointer to the caller

void createBuffer(Buffer **buff, int buffSize){
        *buff = calloc(1, sizeof(Buffer));

a bit simplified : it is similar to

int foo(int a)
{
  a = 1; // 1 not visible outside foo
}

and

int foo(int *a)
{
  *a = 1; // 1 is visible outside foo
}

also in C you don't cast what is returned from calloc/malloc only if you are compiling with a C++ compiler but then you should use new instead

In c, function parameter is passed by value so your createBuffer() function didn't really create anything; it just leaked memory instead.

One easy fix is to allocate the memory in main():

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

and remove this line:

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

I don't see how your createSem() is implemented by you may want to check it too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM