2013-10-11 6 views
1

После поиска по многим темам по подобным проблемам я не смог определить, почему я получаю ошибку seg с моей программой. У меня есть два файла: 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, поэтому я был бы признателен за любые рекомендации. Благодаря!

ответ

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 вы не отбрасывают то, что возвращается из calloc/malloc только если вы компилируете с компилятором C++, но тогда вы должны использовать new вместо

+0

+1, и заметим, что в обоих случаях вы проходите * адрес * переменной, получающей результат. В первом, 'createBuffer (& bufferA, 128);', в последнем, 'int n; foo (&n); ' – WhozCraig

0

В c параметр функции передается по значению, поэтому ваша функция createBuffer() на самом деле ничего не создавала; вместо этого он просто пролистал память.

Одно легко исправить, чтобы выделить память в главном():

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

и удалить эту строку:

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

Я не вижу, как ваш createSem() осуществляется Вами может также проверить его.

Смежные вопросы