Producer Consumer Solution - c

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.

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.

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

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

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?

Related

Void function required to return value?

I wrote a function as follows which is used to create pthread:
void *downloadfile(void *arg)
{
char *req_path = NULL;
char local_path[PATH_BUFFER_SIZE];
int returncode = 0;
gfcrequest_t *gfr = NULL;
FILE *file = NULL;
int i = 0;
/* Build your queue of requests here */
for (i = 0; i < nrequests; i++) {
// pthread mutex locking
// doing something
// pthread mutex unlocking
localPath(req_path, local_path);
file = openFile(local_path);
gfr = gfc_create();
gfc_set_server(&gfr, server);
gfc_set_path(&gfr, req_path);
gfc_set_port(&gfr, port);
gfc_set_writefunc(&gfr, writecb);
gfc_set_writearg(&gfr, file);
fprintf(stdout, "Requesting %s%s\n", server, req_path);
if (0 > (returncode = gfc_perform(&gfr))) {
fprintf(stdout, "gfc_perform returned an error %d\n", returncode);
fclose(file);
if (0 > unlink(local_path))
fprintf(stderr, "warning: unlink failed on %s\n", local_path);
} else {
fclose(file);
}
if (gfc_get_status(&gfr) != GF_OK) {
if (0 > unlink(local_path))
fprintf(stderr, "warning: unlink failed on %s\n", local_path);
}
fprintf(stdout, "Status: %s\n", gfc_strstatus(gfc_get_status(&gfr)));
fprintf(stdout, "Received %zu of %zu bytes\n", gfc_get_bytesreceived(&gfr),
gfc_get_filelen(&gfr));
gfc_cleanup(&gfr);
req_path = NULL;
}
// return 0;
}
I commented out the "return 0;" statement because this is a void function thus should not return any value. But the compiler complains that
error: control reaches end of non-void function
If I uncomment the "return 0;" statement, the error goes away. I am so puzzled. How can the compiler require a void function to return value? Could somebody please help out?
From your description I assume that your function downloadfile is to be used as function-pointer argument in a pthread_create call.
So you have a basic misunderstanding. The function pointer used for pthread_create is not a function pointer to a "void function". It's a function pointer to a function that returns a void pointer. (BTW: You can get the return value using the pthread_join function if needed)
So in other other words: Your function must return a void-pointer. If you have nothing meaningful to return just use return NULL;
Extra details:
From https://man7.org/linux/man-pages/man3/pthread_create.3.html we have:
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void *),
void *restrict arg);
The interresting part here is void *(*start_routine)(void *) which means:
void *(*start_routine)(void *)
\----/\--------------/\------/
| Function ptr |
| to a function /----------\
| that takes void pointer as argument
| and returns
/----------\
void pointer
So again - to use a correct function pointer argument for pthread_create you need a function that returns a void-pointer.
because this is a void function
No it isn't. It is a function returning a void*. Pthreads only work with functions of the signature void* f (void*). That's the only kind of function you can use, as per pthread library design. You don't get to chose anything else.
error: control reaches end of non-void function
This is a nice error to get since your code without the return statement contains undefined behavior. Specifically C17 6.9.1/12 says:
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
As in, if you didn't use return and the caller checks the result - which will happen here inside the pthreads lib, then anything can happen. It is a bug.
If you aren't interested in returning anything from the function, you must return NULL; or the equivalent return 0;.
Notably, the difference between returning void and void* is fundamental C - it is something you should have studied at a much earlier stage before moving on to multi-threading, which is a more advanced topic.

How use atexit() function for free up memory? [duplicate]

I am developing a project in C, and I need to free the allocated memory and also close all the open files before it exits.
I decided to implement a clean function that will do all this stuff and call it with atexit because there are a lot of possible exit scenarios.
The problem is that atexit doesn't allow me to set functions with parameters, so I can't send to clean the pointers that need to be freed in the end of the process.
So I need to declare as global variables every pointer that may need to be freed, and every file that may remaining open in the program? (I already did that but doesn't looks good) or does exist a similar function to atexit that allows to send parameters? or more probably there is another way that I am missing?
Using a static pointer inside a function:
#include <stdio.h>
#include <stdlib.h>
void atexit_clean(void *data);
static void clean(void)
{
atexit_clean(NULL);
}
void atexit_clean(void *data)
{
static void *x;
if (data) {
x = data;
atexit(clean);
} else {
free(x);
}
}
int main(void)
{
int *a = malloc(sizeof(int));
atexit_clean(a);
return 0;
}
Another method using a single global variable: you can store all objects to be freed in an array of pointers or a linked list, this example uses realloc (doesn't check (m/re)alloc for brevity):
#include <stdio.h>
#include <stdlib.h>
static void **vclean;
static size_t nclean;
void atexit_add(void *data)
{
vclean = realloc(vclean, sizeof(void *) * (nclean + 1));
vclean[nclean++] = data;
}
void clean(void)
{
size_t i;
for (i = 0; i < nclean; i++) {
free(vclean[i]);
}
free(vclean);
}
int main(void)
{
int *a, *b, *c;
double *d;
int e = 1;
atexit(clean);
a = &e;
b = malloc(sizeof(int));
atexit_add(b);
c = malloc(sizeof(int));
atexit_add(c);
d = malloc(sizeof(double));
atexit_add(d);
return 0;
}
There is no way to pass any parameters to atexit(), so you're stuck using global variables.
When your program terminates normally, through exit() or by returning from main(), it will automatically flush and close any open streams and (under most operating systems) free allocated memory. However, it is good practice to explicitly clean up your resources before the program terminates, because it typically leads to a more structured program. Sometimes the cleanest way to write your program is to just exit and leave the cleanup to the implementation.
But be warned that you should always check the return value of fclose(). See "What are the reasons to check for error on close()?" for an anecdote about what could happen when you don't.

Accessing the variable inside another code

Is there a way to access a variable initialized in one code from another code. For eg. my code1.c is as follows,
# include <stdio.h>
int main()
{
int a=4;
sleep(99);
printf("%d\n", a);
return 0;
}
Now, is there any way that I can access the value of a from inside another C code (code2.c)? I am assuming, I have all the knowledge of the variable which I want to access, but I don't have any information about its address in the RAM. So, is there any way?
I know about the extern, what I am asking for here is a sort of backdoor. Like, kind of searching for the variable in the RAM based on some properties.
Your example has one caveat, set aside possible optimizations that would make the variable to dissapear: variable a only exists while the function is being executed and has not yet finished.
Well, given that the function is main() it shouldn't be a problem, at least, for standard C programs, so if you have a program like this:
# include <stdio.h>
int main()
{
int a=4;
printf("%d\n", a);
return 0;
}
Chances are that this code will call some functions. If one of them needs to access a to read and write to it, just pass a pointer to a as an argument to the function.
# include <stdio.h>
int main()
{
int a=4;
somefunction(&a);
printf("%d\n", a);
return 0;
}
void somefunction (int *n)
{
/* Whatever you do with *n you are actually
doing it with a */
*n++; /* actually increments a */
}
But if the function that needs to access a is deep in the function call stack, all the parent functions need to pass the pointer to a even if they don't use it, adding clutter and lowering the readability of code.
The usual solution is to declare a as global, making it accessible to every function in your code. If that scenario is to be avoided, you can make a visible only for the functions that need to access it. To do that, you need to have a single source code file with all the functions that need to use a. Then, declare a as static global variable. So, only the functions that are written in the same source file will know about a, and no pointer will be needed. It doesn't matter if the functions are very nested in the function call stack. Intermediate functions won't need to pass any additional information to make a nested function to know about a
So, you would have code1.c with main() and all the functions that need to access a
/* code1.c */
# include <stdio.h>
static int a;
void somefunction (void);
int main()
{
a=4;
somefunction();
printf("%d\n", a);
return 0;
}
void somefunction (void)
{
a++;
}
/* end of code1.c */
About trying to figure out where in RAM is a specific variable stored:
Kind of. You can travel across function stack frames from yours to the main() stack frame, and inside those stack frames lie the local variables of each function, but there is no sumplementary information in RAM about what variable is located at what position, and the compiler may choose to put it wherever it likes within the stack frame (or even in a register, so there would be no trace of it in RAM, except for push and pops from/to general registers, which would be even harder to follow).
So unless that variable has a non trivial value, it's the only local variable in its stack frame, compiler optimizations have been disabled, your code is aware of the architecture and calling conventions being used, and the variable is declared as volatile to stop being stored in a CPU register, I think there is no safe and/or portable way to find it out.
OTOH, if your program has been compiled with -g flag, you might be able to read debugging information from within your program and find out where in the stack frame the variable is, and crawl through it to find it.
code1.c:
#include <stdio.h>
void doSomething(); // so that we can use the function from code2.c
int a = 4; // global variable accessible in all functions defined after this point
int main()
{
printf("main says %d\n", a);
doSomething();
printf("main says %d\n", a);
return 0;
}
code2.c
#include <stdio.h>
extern int a; // gain access to variable from code1.c
void doSomething()
{
a = 3;
printf("doSomething says %d\n", a);
}
output:
main says 4
doSomething says 3
main says 3
You can use extern int a; in every file in which you must use a (code2.c in this case), except for the file in which it is declared without extern (code1.c in this case). For this approach to work you must declare your a variable globally (not inside a function).
One approach is to have the separate executable have the same stack layout as the program in question (since the variable is placed on the stack, and we need the relative address of the variable), therefore compile it with the same or similar compiler version and options, as much as possible.
On Linux, we can read the running code's data with ptrace(PTRACE_PEEKDATA, pid, …). Since on current Linux systems the start address of the stack varies, we have to account for that; fortunately, this address can be obtained from the 28th field of /proc/…/stat.
The following program (compiled with cc Debian 4.4.5-8 and no code generator option on Linux 2.6.32) works; the pid of the running program has to be specified as the program argument.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ptrace.h>
void *startstack(char *pid)
{ // The address of the start (i. e. bottom) of the stack.
char str[FILENAME_MAX];
FILE *fp = fopen(strcat(strcat(strcpy(str, "/proc/"), pid), "/stat"), "r");
if (!fp) perror(str), exit(1);
if (!fgets(str, sizeof str, fp)) exit(1);
fclose(fp);
unsigned long address;
int i = 28; char *s = str; while (--i) s += strcspn(s, " ") + 1;
sscanf(s, "%lu", &address);
return (void *)address;
}
static int access(void *a, char *pidstr)
{
if (!pidstr) return 1;
int pid = atoi(pidstr);
if (ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) return perror("PTRACE_ATTACH"), 1;
int status;
// wait for program being signaled as stopped
if (wait(&status) < 0) return perror("wait"), 1;
// relocate variable address to stack of program in question
a = a-startstack("self")+startstack(pidstr);
int val;
if (errno = 0, val = ptrace(PTRACE_PEEKDATA, pid, a, 0), errno)
return perror("PTRACE_PEEKDATA"), 1;
printf("%d\n", val);
return 0;
}
int main(int argc, char *argv[])
{
int a;
return access(&a, argv[1]);
}
Another, more demanding approach would be as mcleod_ideafix indicated at the end of his answer to implement the bulk of a debugger and use the debug information (provided its presence) to locate the variable.

Exists a way to free memory in atexit or similar without using global variables?

I am developing a project in C, and I need to free the allocated memory and also close all the open files before it exits.
I decided to implement a clean function that will do all this stuff and call it with atexit because there are a lot of possible exit scenarios.
The problem is that atexit doesn't allow me to set functions with parameters, so I can't send to clean the pointers that need to be freed in the end of the process.
So I need to declare as global variables every pointer that may need to be freed, and every file that may remaining open in the program? (I already did that but doesn't looks good) or does exist a similar function to atexit that allows to send parameters? or more probably there is another way that I am missing?
Using a static pointer inside a function:
#include <stdio.h>
#include <stdlib.h>
void atexit_clean(void *data);
static void clean(void)
{
atexit_clean(NULL);
}
void atexit_clean(void *data)
{
static void *x;
if (data) {
x = data;
atexit(clean);
} else {
free(x);
}
}
int main(void)
{
int *a = malloc(sizeof(int));
atexit_clean(a);
return 0;
}
Another method using a single global variable: you can store all objects to be freed in an array of pointers or a linked list, this example uses realloc (doesn't check (m/re)alloc for brevity):
#include <stdio.h>
#include <stdlib.h>
static void **vclean;
static size_t nclean;
void atexit_add(void *data)
{
vclean = realloc(vclean, sizeof(void *) * (nclean + 1));
vclean[nclean++] = data;
}
void clean(void)
{
size_t i;
for (i = 0; i < nclean; i++) {
free(vclean[i]);
}
free(vclean);
}
int main(void)
{
int *a, *b, *c;
double *d;
int e = 1;
atexit(clean);
a = &e;
b = malloc(sizeof(int));
atexit_add(b);
c = malloc(sizeof(int));
atexit_add(c);
d = malloc(sizeof(double));
atexit_add(d);
return 0;
}
There is no way to pass any parameters to atexit(), so you're stuck using global variables.
When your program terminates normally, through exit() or by returning from main(), it will automatically flush and close any open streams and (under most operating systems) free allocated memory. However, it is good practice to explicitly clean up your resources before the program terminates, because it typically leads to a more structured program. Sometimes the cleanest way to write your program is to just exit and leave the cleanup to the implementation.
But be warned that you should always check the return value of fclose(). See "What are the reasons to check for error on close()?" for an anecdote about what could happen when you don't.

Most Desirable Way To Handle Function Error Messages?

Let's say I have a function to perform a small and particular task that has a fairly good possibility of failure. What is the best way to handle something going wrong? (Assuming I know what the problem is).
For example lets say I have a function that reads a two byte string and returns it:
#include <stdio.h>
#include <stdlib.h>
char *bar(void)
{
char *foo = malloc(3);
scanf("%2s", foo);
return foo;
}
int main(void)
{
char *foo = bar();
puts(foo);
free(foo);
return 0;
}
The above example has absolutely no error handling whatsoever. There are two ways that I would implement some sort of error handling, but I'm not sure which would be more preferred or considered best practice.
Method 1 (print error message To stderr from within the function):
#include <stdio.h>
#include <stdlib.h>
char *bar(void)
{
char *foo;
if(!(foo = malloc(3)))
{
fputs("\nError! Memory allocation failed.", stderr);
return 0x00;
}
scanf("%2s", foo);
return foo;
}
int main(void)
{
char *foo;
if(!(foo = bar())) return 1;
puts(foo);
free(foo);
return 0;
}
Method 2 (print error message to stderr from the calling function):
#include <stdio.h>
#include <stdlib.h>
char *bar(void)
{
char *foo;
if(!(foo = malloc(3))) return 0x00;
scanf("%2s", foo);
return foo;
}
int main(void)
{
char *foo;
if(!(foo = bar()))
{
fputs("\nError! Memory allocation failed.", stderr);
return 1;
}
puts(foo);
free(foo);
return 0;
}
I'm almost thinking that method two would be the best way to go because that way I could get more specific with my error messages depending on what I'm calling that function for at the time.
What I worry about with method two is the fact that I lose the ability to print what specifically went wrong in the function if it has more than one potential point of failure.
Pseudo Code:
IF FAILUREA
PRINT "FAILUREA OCCURED"
RETURN
IF FAILUREB
PRINT "FAILUREB OCCURED"
RETURN
This wouldn't be much of a problem if the function I was calling was an int because then I could just return a different integer value based on what went wrong. But in the case of a char* I typically try to return NULL on failure (so both FAILUREA and FAILUREB would be returning NULL); there would be no way to know what caused the function to fail.
So my question is what is best practice when it comes to handling error messages?
Allowing the caller to handle error reporting is better because:
if the function is forming part of a library stderr may not be available and an alternative reporting mechanism is required.
the calling code may have an alternative action that can be taken and may not deem the failure of function bar() as an actual failure and have no need to report it.
If a function has multiple possible failure reasons then a possibility is to pass an argument to the function that is updated in the event of failure. The calling function can then choose an appropriate action depending on the actual failure reason. For example:
enum Status
{
STATUS_OK,
STATUS_MEMORY_ALLOCATION_FAILURE,
STATUS_ACCESS_DENIED
};
enum Status status;
char* foo = bar(&status);
if (!foo)
{
if (STATUS_MEMORY_ALLOCATION_FAILURE == status)
{
/* report failure. */
}
else if (STATUS_ACCESS_DENIED == status)
{
/* try somewhere else */
}
}
If you can do anything about a failure and if you are going to, then you do it.
Otherwise, you may implement a generic failure function, call it in case of an error and call it a day:
void error(const char* format, ...)
{
va_list vl;
va_start(vl, format);
vfprintf(stderr, format, vl);
va_end(vl);
exit(-1);
}
You can optionally wrap it in a macro supplying it with the line# and file name:
#define ERROR(fmt, ...) \
error("file:'%s',line:%d " fmt, __FILE__, __LINE__, __VA_ARGS__)
This will make errors in the console very easy to figure out because the error messages tell precisely the file and the line in it where the error has occurred.
Typical usage, nothing fancy:
char *bar(void)
{
char *foo;
if ((foo=malloc(3)) == NULL)
ERROR("malloc() failed!\n");
if (scanf("%2s", foo) != 1)
ERROR("scanf() failed!\n");
return foo;
}
You may use longjmp() in place of exit(-1) to immediately return to the caller (=the one that did the respective setjmp()) if you want to actually do something upon the error, maybe close all files open for writing, so the buffered data isn't lost.
If you're writing a simple compiler, for example, this kind of error() is more than enough for most errors internal to the compiler and for problems in the source code being compiled (e.g. a missing colon/paren or something else that makes the code not compilable).
If you cannot or do not want to do any of that, you need to carefully write the code, do proper clean ups and return different error codes to communicate actionable errors to the caller.
You can do in this way if your function return more than 1 error case
#include <stdio.h>
#include <stdlib.h>
int bar(char **foo)
{
if(!(malloc(3))) return 1; /* return error case 1*/
scanf("%2s", *foo);
if(!(malloc(4))) return 2; /* return error case 2*/
return 0; /* no error*/
}
int catcherror(int error)
{
switch (error) {
case 1:
/*do something 1*/
case 2:
/*do something 1*/
case 3:
/*do something 1*/
case 4:
/*do something 1*/
case 5:
/*do something 1*/
default:
/*do something 1*/
}
}
int main(void)
{
char *foo;
int error
error = bar(&foo);
catcherror(error);
puts(foo);
free(foo);
return 0;
}
The catcherror() function could be very useful if your project contains many functions which return a common error cases

Resources