-1

I've developed the producer / consumer problem in C and for some reason it doesn't compile. I'm getting the error message:

 try1.c: In function ‘main’:

try1.c:19:21: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]

       BUFFER=(char *) malloc(sizeof(char) * BufferSize);

Please could someone identify the issue? Have tried for a while to fix this now however haven't had any luck.

#include <stdio.h>
#include <pthread.h>
#define BufferSize 10

void *Producer();
void *Consumer();

int BufferIndex=0;
char *BUFFER;

pthread_cond_t Buffer_Not_Full=PTHREAD_COND_INITIALIZER;
pthread_cond_t Buffer_Not_Empty=PTHREAD_COND_INITIALIZER;
pthread_mutex_t mVar=PTHREAD_MUTEX_INITIALIZER;

int main()
{    
    pthread_t ptid,ctid;

    BUFFER=(char *) malloc(sizeof(char) * BufferSize);            

    pthread_create(&ptid,NULL,Producer,NULL);
    pthread_create(&ctid,NULL,Consumer,NULL);

    pthread_join(ptid,NULL);
    pthread_join(ctid,NULL);


    return 0;
}

void *Producer()
{    
    for(;;)
    {
        pthread_mutex_lock(&mVar);
        if(BufferIndex==BufferSize)
        {                        
            pthread_cond_wait(&Buffer_Not_Full,&mVar);
        }                        
        BUFFER[BufferIndex++]='@';
         printf("Produce : %d \n",BufferIndex);
        pthread_mutex_unlock(&mVar);
        pthread_cond_signal(&Buffer_Not_Empty);        
    }    

}

void *Consumer()
{
    for(;;)
    {
        pthread_mutex_lock(&mVar);
        if(BufferIndex==-1)
         {            
             pthread_cond_wait(&Buffer_Not_Empty,&mVar);
         }                
        printf("Consume : %d \n",BufferIndex--);        
        pthread_mutex_unlock(&mVar);        
        pthread_cond_signal(&Buffer_Not_Full);                
    }    
}

Thanks a lot for your help.

SergeyA
  • 61,605
  • 5
  • 78
  • 137

4 Answers4

1

First of all, this question has nothing to do with producer/consumer. It has to do with the use of a function you didn't declare.

Historically, C allowed calling a function which was never declared. Since technically function declaration is not needed to call it, compiler gladly added instructions to call the unknown function. Allegedly, it allowed developers to save precious keystrokes. However, you need a function declaration to know it's return value, and compiler assumed that return value of such a function is int. And you are having just that - an implicitly declared malloc() with assumed return type of int.

Now, compiler knows what malloc() is. It is often built-in intrinstic function. However, compiler also knows that return value of said malloc() is void*, not int - and thus it complains.

Solution - get rid of implicit declaration, and make a habit of always including apropriate header files for every function you are using.

You also have issues with the way you are using conditional variables, but I would leave it for another question.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
1

The producer should go to sleep when the buffer is full. Next time when the consumer removes data it notifies the producer and producer start producing data again. The consumer should go to sleep when a buffer is empty. Next time when producer adds data it notifies the consumer and consumer starts consuming data. This solution can be achieved using semaphores.

#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>
#include <semaphore.h>
int mutex=1,full=0,empty=3,x=0;

int main()
{
    int n;
    void producer(void);
    void consumer(void);
    int waiting(int);
    int signaling(int);
    printf("\n1.Producer\n2.Consumer\n3.Exit");
    while(1)
    {
        printf("\nEnter your choice:");
        scanf("%d",&n);
        switch(n)
        {
            case 1: if((mutex==1)&&(empty!=0))
                producer();
            else
                printf("Buffer is full!!");
                break;
            case 2:    if((mutex==1)&&(full!=0))
                consumer();
            else
                printf("Buffer is empty!!");
                break;
            case 3:
                exit(0);
                break;
        }
    }

    return 0;
}

int waiting(int s)
{
    return (--s);
}

int signaling(int s)
{
    return(++s);
}

void producer()
{
    mutex=wait(&mutex);
    full=signaling(full);
    empty=wait(&empty);
    x++;
    printf("\nProducer produces the item %d",x);
    mutex=signaling(mutex);
}

void consumer()
{
    mutex=wait(&mutex);
    full=wait(&full);
    empty=signaling(empty);
    printf("\nConsumer consumes item %d",x);
    x--;
    mutex=signaling(mutex);
}
Héctor M.
  • 2,302
  • 4
  • 17
  • 35
Adarsh Pawar
  • 682
  • 6
  • 15
0

Just include the stdlib.h library. This library will include the malloc() function.

Ichigo-San
  • 79
  • 1
  • 8
0

You are using malloc without including the header file that declares it (stdlib.h).

Your usage (without that explicit declaration from stdlib.h) creates an "implicit declaration" which doesn't match the one the compiler knows about because yours returns char* and the proper malloc returns void*.

So add include <stdlib.h> and also note that you shouldn't cast the result of a malloc. See Do I cast the result of malloc?

Community
  • 1
  • 1
GrahamS
  • 9,980
  • 9
  • 49
  • 63
  • Correct up to the point of `doesn't match the one the compiler knows about ... ` - than incorrect :) – SergeyA Apr 18 '16 at 17:07
  • You just said in your own answer that the "compiler knows what malloc is". How else can it complain "incompatible implicit declaration of built-in function ‘malloc’" when the `malloc` function hasn't been declared? – GrahamS Apr 18 '16 at 17:10
  • I did. And I stand by my answer and my comment. Hint - the idea that compiler knows about malloc is correct. It is the *return type* of it part which is incorrect. Read my answer to see the correct one. – SergeyA Apr 18 '16 at 17:13
  • Okay, I see. I thought the compiler was allowed to derive the return type of the implicit declaration from the context. But it seems not. Thanks for the correction. The point about not casting the result of `malloc` remains though. – GrahamS Apr 18 '16 at 17:30
  • I am a strong proponent of not casting return type of malloc myself :) – SergeyA Apr 18 '16 at 17:32