Hi guys I'm having trouble with this code
int file_id;
void* wraper(void* p){
return (void)reader((int)p);
}
int main(int argc, char *argv[]){
srandom ((unsigned) time(NULL));
int i;
pthread_t tid[3];
for(i=0;i<3;i++){
pthread_t * temp = malloc(sizeof(tid[i]));
file_id=get_random(NB_FILES);
pthread_create(&tid[i], NULL,wraper,(void*)file_id);
}
and the compiler is giving me this
reader-thread.c: In function ‘wraper’:
reader-thread.c:59:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
return (void)reader((int)p);
^
reader-thread.c:59:5: error: void value not ignored as it ought to be
return (void)reader((int)p);
^
reader-thread.c: In function ‘main’:
reader-thread.c:70:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
pthread_create(&tid[i], NULL,wraper,(void*)file_id);
^
The objective is to create 3 threads and send them the file_id to the function reader, I can't see what I'm doing wrong
Your compiler is correct, you shouldn't ignore this, on many architectures pointers and int don't have the same width. The correct type, if you really have to, is to use uintptr_t or intptr_t.
Also casting the return of the function (that you didn't show us) to (void) makes no sense if you have to return a void*.
Casting the other way around from int to void* is almost as bad as 1.
In essence you shouldn't try to violate the call interface for thread functions. If you have to transmit data, pass a pointer to the data.
Also, please, when you post a question here, be sure that the error messages correspond to the code that you posted.
Related
I want to implement a stack using structures in C. Unfortunately, printf throws a segmentation fault. Perhaps there is a problem with dynamic allocation. Does anyone know how to solve it?
I have been facing this issue for the last two days. Your help will be very helpful for my study.
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 256
typedef int (*pf)();
typedef struct _stack{
int arr[SIZE];
int top;
pf push, pop, peek, isEmpty, size, clear, print;
} stack;
void *nstack(){
stack *pstack = (stack *)malloc(sizeof(stack));
void push(int data) {
if(pstack->top < SIZE-1) pstack->arr[++pstack->top]=data;
}
int pop() {
return (pstack->top >= 0)?pstack->arr[pstack->top--]:0;
}
int peek(){
return (pstack->top >= 0)?pstack->arr[pstack->top]:0;
}
bool isEmpty(){
return (pstack->top >= 0)?false:true;
}
int size(){
return pstack->top+1;
}
void clear(){
pstack->top = -1;
}
void print(){
if(!isEmpty()){
for(int i = 0; i <= pstack->top; i++) printf("%d", pstack->arr[i]);
printf("\n");
}
}
pstack->push=push;
pstack->pop=pop;
pstack->peek=peek;
pstack->isEmpty=isEmpty;
pstack->size=size;
pstack->clear=clear;
pstack->print=print;
pstack->top=-1;
return pstack;
}
void dstack(stack *pstack){
free(pstack);
}
void main() {
stack *A = nstack();
A->push(1);
A->push(4);
A->push(6);
printf("%d",A->pop());
printf("%d",A->pop());
dstack(A);
}
While the code compiles (with warning), it try to leverage GCC extensions for functions within functions. However, the internal functions must be called within a valid context - they try to access the local pstackof the nstack function - but it does not exists.
While this style work in many OO langauges (Java, and possibly C++), that support 'closures' or lambda, it does not work for C. Consider changing the interface for each of the function to take stack *, and change the calling sequence to pass it.
void push(stack *pstack, int data) {
if(pstack->top < SIZE-1) pstack->arr[++pstack->top]=data;
}
main() {
...
A->push(A, 1) ;
...
printf("%d", A->pop(A) ;
}
Really, you should edit your question and provide the exact errors but I've decided to do some of the legwork for you since you're probably pretty new to this.
So first thing I did was compile your code here with -Wall and look what I get:
SO_stack.c: In function ‘nstack’:
SO_stack.c:49:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->push=push;
^
SO_stack.c:52:20: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->isEmpty=isEmpty;
^
SO_stack.c:54:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->clear=clear;
^
SO_stack.c:55:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->print=print;
^
SO_stack.c: At top level:
SO_stack.c:66:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main() {
Let's look at the first error on line 49: pstack->push=push;
You've defined push function prototype as: void push(int data) but pstack->push is of type pf which is defined as int (*pf)(); See the problem here? You're trying to pass an argument to a function pointer that is not properly defined to handle the argument AND the return type is different. This is totally wrong. Your push(int data) implementation declares a return type of void and a parameter of int yet your pointer to this function declares a return type of int and a parameter of void. This is the case with push, isEmpty, clear, and print. You're going to have to decide if all of these functions need to have the same prototype or if you need to create several different function pointer types to handle them, etc...
So that's the first problem.
Second problem is that as the warning says, you have a void main() prototype for your main function. You should return int from main and specify a return code to the caller of main (likely the OS)... Commonly, successful execution returns 0 and failure returns -1 but this is specific to the platform so you can instead return EXIT_SUCCESS on success and return EXIT_FAILURE upon failure from main. For this macros to be defined, you need to have #include <stdlib.h> present, which you do.
Next issue is that as a commenter wrote, you should learn to use a debugger such as GDB, LLDB, or Windows Debugger so that you can figure out exactly where the program crashes.
I've not re-written your program because it has so many issues that I don't think it would be constructive to do so in this iteration, however, provide an exact error next time, and use the debugger to see if the crash happens inside of the actual printf() code as you implied, or it happens because you supplied corrupt memory to the printf function. My guess is that it is the latter... Meaning, it is in fact probably your code which is flawed and supplying an invalid char * to printf which is either out of bounds, nonexistent, etc... This is precisely what you will use a debugger to find out, by placing a breakpoint before the trouble code and watching the memory to see what's going on.
You need to either remove int data.
Work on this some more, and you will probably find the rest of the issues yourself, if there are any. You should compile with flag -Wall and consider compiling with flag -Werror to clear this kind of stuff up yourself in the future.
I wrote this small program for understanding pthread_create and pthread_join but I dont understand why the value of the variable data gets altered after thread_join. Its printed as 0 after the call to pthread functions.
#include <pthread.h>
#include <stdio.h>
void* compute_prime (void* arg)
{
int n = *((int*) arg);
printf("Argument passed is %d\n",n);
return (void *)n;
}
int main ()
{
pthread_t thread;
int data = 5000;
int value=0;
pthread_create (&thread, NULL, &compute_prime, &data);
pthread_join (thread, (void*) &value);
printf("The number is %d and return value is %d.\n", data, value);
return 0;
}
And the output is
Argument passed is 5000
The number is 0 and return value is 5000.
This is because pthread_join has the prototype void **. It expects a pointer to an object of type void *; it modifies this void * object. Now it so happens that you're running on a 64-bit arch, where data and value are both 32 bits, and laid out in memory sequentially. Modifying a void * object that is laid out in memory starting from the address of the int object value clobbers the int object data too, as these are both 32 bits - thus you will see that the data was overwritten. However, this is undefined behaviour so anything might happen.
Don't use casts as they will only serve to hide problems. Casting to a void * is especially dangerous as a void * can be converted to any other type implicitly, even to void **, even though usually it too would be incorrect. If you remove the cast, you most probably will get a warning or an error like
thrtest.c: In function ‘main’:
thrtest.c:16:31: error: passing argument 2 of ‘pthread_join’ from
incompatible pointer type [-Werror=incompatible-pointer-types]
pthread_join (thread, &value);
if compiling with warnings enabled.
If however you really want to do this, you must do it like this:
void *value;
pthread_join(thread, &value);
intptr_t value_as_int = (intptr_t)value;
Though it is not really portable either, as the conversion is implementation-defined.
The most portable way to return an integer is to return a pointer to a mallocated object:
int *return_value = malloc(sizeof (int));
*return_value = 42;
return return_value;
...
void *value;
pthread_join(thread, &value);
int actual = *(int *)value;
free(value);
The following code displays an error if the Storage Class of the parameters of the function int *check(register int,register int); declared as some other Storage Class.
I compiled this code on Code::Blocks 10.05 IDE with GNU GCC Compiler. What is the reason behind the error? Is it a compiler specific error or a general one?
The code section begins from here:
int *check(register int, register int);
int main()
{
int *c;
c = check(10, 20);
printf("%d\n", c);
return 0;
}
int *check(register int i,register int j)
{
int *p = i;
int *q = j;
if(i >= 45)
return (p);
else
return (q);
}
int *check(register int i,register int j)
{
int *p=i;
int *q=j;
Type mismatch of p q and i j. Perhaps what you want is :
int *check(int i, int j)
{
int *p=&i;
int *q=&j;
Correction: Note that register cannot be used with &. Besides, the keyword register has little usage because the compiler usually ignores it and does the optimization itself.
int *check(register int i,register int j)
{
int *p=i;
int *q=j;
if(i >= 45)
return (p);
else
return (q);
}
While register storage class specifier is allowed on parameter declaration, parameters i and j have int type while p and q are of type int *. This makes the declaration of p and q invalid.
You cannot just change this to:
int *p=&i;
int *q=&j;
as the & operator does not allow you to have an operand of register storage class.
You cannot also also change the parameter declaration from register int i and register int j to int i and int j and then return the address of i and j object as their lifetime ends at the exit of the function.
In your case you should just not use pointers: use int parameters and an int return value.
First type mismatch:
int *p=i;
int *q=j;
Second side note & not applied/valid on register variables.
From: address of register variable in C and C++
In C, you cannot take the address of a variable with register storage. Cf. C11 6.7.1/6:
A declaration of an identifier for an object with storage-class specifier register
suggests that access to the object be as fast as possible. The extent to which such
suggestions are effective is implementation-defined.
third: Returning address of local object is Undefined behavior (and parameters of functions counts in local variables). Don't return address of that there life is till function returns.
Suggestion:
To return address, you need to do dynamic allocation and return address of that. for example:
int *check(int i,int j){
int *p= malloc(sizeof (int));
int *q= malloc(sizeof (int));
*p = i;
*q = j;
if(i >= 45){
free(q);
return (p);
}
else{
free(p);
return (q);
}
}
Note returned address is not of i, j, but its address of dynamically allocated memory. Don't forget to call free(a) in main().
In my machine with GCC 4.7.3 on Ubuntu 13.04, the output is
$gcc test.c
test.c: In function ‘main’:
test.c:7:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
test.c:7:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
test.c: In function ‘check’:
test.c:13:12: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:14:12: warning: initialization makes pointer from integer without a cast [enabled by default]
$./a.out
20
It accepts the program with a lot of warnings. And there is not a single word says "storage class". so I wonder what version of GCC you are using?
The first two warnings can be fixed by #include <stdio.h> and change %d in the printf function call to %p. Let's ignore those for now and focus on the rest two. Depends on what you want to do, you can have different options to eliminate them.
If you want to return the address of i or j as a stack based variable (which is unusual because it is invalid after return to the caller), you can do
int *check( int i, int j)
{
int *p = &i;
int *q = &j;
...
You cannot obtain the address of a register variable, so you have to remove them. In this case, with your main function your program will print something like 0x7fffc83021f8 in my machine. That is the pointer value to the variable j, although it is not valid at the time we prints it, as long as you do not attempt to dereference it everything is OK.
If this is not what you want, you probably want to force the integer i or j to represent a pointer, then you need to do
int *check(register int i,register int j)
{
int *p=(int *)i;
int *q=(int *)j;
if(i >= 45)
return (p);
else
return (q);
}
Note in this case the use of register keyword is OK although it may have very limited effect. Also this would still warn you when you compile the code in some machine (especially 64 bit GCC).
Although strange, but this code have some sense: usually an integer that too close to zero is not a valid pointer.
So what this code does is: it returns i's value as a pointer if it's a valid pointer(value greater than 45), or return js value. The result in this case is 0x14 (remember we need to replace %d to %p, so the output is in hexadecimal).
EDIT
After look at your main function I believe what is wanted here would be
int check(register int i,register int j)
{
int p=i;
int q=j;
if(i >= 45)
return (p);
else
return (q);
}
But anyway this code can be simplified as
int check(register int i,register int j)
{
if(i >= 45)
return i;
else
return j;
}
or even
int check(register int i,register int j)
{
return i>=45 ? i : j;
}
in these cases the main function should be
int main()
{
int c;
c = check(10, 20);
printf("%d\n", c);
return 0;
}
Note since the data type of c is now int so the %p for printf is restored back to %d. The output is the same of the original code: 20.
OK now I see what you are asking.
If you have a function prototype declaration like this:
int *check(register int, register int);
As soon as the compiler sees this, it can enforce a rule that no code will attempt to obtain the address of the parameters. It is up to the compiler to consider a consistent way to generate code for function calls through out the program based on this fact. This may or may not be the same as
int *check(int, int);
Which performs the default treatment of parameters (but again the compiler will ensure it is consistent through out the program).
But consider the following:
int *check(auto int, auto int);
The compiler do not know weather the address of the parameter is going to be used or not unless it sees the actual implementation. So it cannot assume anything. The programmer obviously want some optimization, but the compiler do not have any further information to do so.
So it does not make sense to specify a parameter to be auto.
What if use auto for parameters of function definition? Again this makes little sense. The compiler can have a strategy that if there is no attempt to obtain the parameter address then treat it as register other use stack for it. But for parameters that do not use auto the rule would be the same. So it does not gives the compiler any further information.
Other storage classes are even makes no sense for parameters in function definition. It is not possible to pass a parameter through static data area or the heap (you can only pass pointers - which actually in the stack or registers).
I want to the know the problems with the code presented below. I seem to be getting a segmentation fault.
void mallocfn(void *mem, int size)
{
mem = malloc(size);
}
int main()
{
int *ptr = NULL;
mallocfn(ptr, sizeof(ptr));
*ptr = 3;
return;
}
Assuming that your wrapper around malloc is misnamed in your example (you use AllocateMemory in the main(...) function) - so I'm taking it that the function you've called malloc is actually AllocateMemory, you're passing in a pointer by value, setting this parameter value to be the result of malloc, but when the function returns the pointer that was passed in will not have changed.
int *ptr = NULL;
AllocateMemory(ptr, sizeof(ptr));
*ptr = 3; // ptr is still NULL here. AllocateMemory can't have changed it.
should be something like:
void mallocfn(void **mem, int size)
void mallocfn(int **mem, int size)
{
*mem = malloc(size);
}
int main()
{
int *ptr = NULL;
mallocfn(&ptr, sizeof(ptr));
*ptr = 3;
return;
}
Because you need to edit the contents of p and not something pointed b p, so you need to send the pointer variable p's address to the allocating function.
Also check #Will A 's answer
Keeping your example, a proper use of malloc would look more like this:
#include <stdlib.h>
int main()
{
int *ptr = NULL;
ptr = malloc(sizeof(int));
if (ptr != NULL)
{
*ptr = 3;
free(ptr);
}
return 0;
}
If you're learning C I suggest you get more self-motivated to read error messages and come to this conclusion yourself. Let's parse them:
prog.c:1: warning: conflicting types for built-in function ‘malloc’
malloc is a standard function, and I guess gcc already knows how it's declared, treating it as a "built-in". Typically when using standard library functions you want to #include the right header. You can figure out which header based on documentation (man malloc).
In C++ you can declare functions that have the same name as already existing functions, with different parameters. C will not let you do this, and so the compiler complains.
prog.c:3: warning: passing argument 1 of ‘malloc’ makes pointer from integer without a cast
prog.c:3: error: too few arguments to function ‘malloc’
Your malloc is calling itself. You said that the first parameter was void* and that it had two parameters. Now you are calling it with an integer.
prog.c:8: error: ‘NULL’ undeclared (first use in this function)
NULL is declared in standard headers, and you did not #include them.
prog.c:9: warning: implicit declaration of function ‘AllocateMemory’
You just called a function AllocateMemory, without telling the compiler what it's supposed to look like. (Or providing an implementation, which will create a linker error.)
prog.c:12: warning: ‘return’ with no value, in function returning non-void
You said that main would return int (as it should), however you just said return; without a value.
Abandon this whole idiom. There is no way to do it in C without making a separate allocation function for each type of object you might want to allocate. Instead use malloc the way it was intended to be used - with the pointer being returned to you in the return value. This way it automatically gets converted from void * to the right pointer type on assignment.
Even though it is possible to write generic code in C using void pointer(generic pointer), I find that it is quite difficult to debug the code since void pointer can take any pointer type without warning from compiler.
(e.g function foo() take void pointer which is supposed to be pointer to struct, but compiler won't complain if char array is passed.)
What kind of approach/strategy do you all use when using void pointer in C?
The solution is not to use void* unless you really, really have to. The places where a void pointer is actually required are very small: parameters to thread functions, and a handful of others places where you need to pass implementation-specific data through a generic function. In every case, the code that accepts the void* parameter should only accept one data type passed via the void pointer, and the type should be documented in comments and slavishly obeyed by all callers.
This might help:
comp.lang.c FAQ list · Question 4.9
Q: Suppose I want to write a function that takes a generic pointer as an argument and I want to simulate passing it by reference. Can I give the formal parameter type void **, and do something like this?
void f(void **);
double *dp;
f((void **)&dp);
A: Not portably. Code like this may work and is sometimes recommended, but it relies on all pointer types having the same internal representation (which is common, but not universal; see question 5.17).
There is no generic pointer-to-pointer type in C. void * acts as a generic pointer only because conversions (if necessary) are applied automatically when other pointer types are assigned to and from void * 's; these conversions cannot be performed if an attempt is made to indirect upon a void ** value which points at a pointer type other than void *. When you make use of a void ** pointer value (for instance, when you use the * operator to access the void * value to which the void ** points), the compiler has no way of knowing whether that void * value was once converted from some other pointer type. It must assume that it is nothing more than a void *; it cannot perform any implicit conversions.
In other words, any void ** value you play with must be the address of an actual void * value somewhere; casts like (void **)&dp, though they may shut the compiler up, are nonportable (and may not even do what you want; see also question 13.9). If the pointer that the void ** points to is not a void *, and if it has a different size or representation than a void *, then the compiler isn't going to be able to access it correctly.
To make the code fragment above work, you'd have to use an intermediate void * variable:
double *dp;
void *vp = dp;
f(&vp);
dp = vp;
The assignments to and from vp give the compiler the opportunity to perform any conversions, if necessary.
Again, the discussion so far assumes that different pointer types might have different sizes or representations, which is rare today, but not unheard of. To appreciate the problem with void ** more clearly, compare the situation to an analogous one involving, say, types int and double, which probably have different sizes and certainly have different representations. If we have a function
void incme(double *p)
{
*p += 1;
}
then we can do something like
int i = 1;
double d = i;
incme(&d);
i = d;
and i will be incremented by 1. (This is analogous to the correct void ** code involving the auxiliary vp.) If, on the other hand, we were to attempt something like
int i = 1;
incme((double *)&i); /* WRONG */
(this code is analogous to the fragment in the question), it would be highly unlikely to work.
Arya's solution can be changed a little to support a variable size:
#include <stdio.h>
#include <string.h>
void swap(void *vp1,void *vp2,int size)
{
char buf[size];
memcpy(buf,vp1,size);
memcpy(vp1,vp2,size);
memcpy(vp2,buf,size); //memcpy ->inbuilt function in std-c
}
int main()
{
int array1[] = {1, 2, 3};
int array2[] = {10, 20, 30};
swap(array1, array2, 3 * sizeof(int));
int i;
printf("array1: ");
for (i = 0; i < 3; i++)
printf(" %d", array1[i]);
printf("\n");
printf("array2: ");
for (i = 0; i < 3; i++)
printf(" %d", array2[i]);
printf("\n");
return 0;
}
The approach/strategy is to minimize use of void* pointers. They are needed in specific cases. If you really need to pass void* you should pass size of pointer's target also.
This generic swap function will help you a lot in understanding generic void *
#include<stdio.h>
void swap(void *vp1,void *vp2,int size)
{
char buf[100];
memcpy(buf,vp1,size);
memcpy(vp1,vp2,size);
memcpy(vp2,buf,size); //memcpy ->inbuilt function in std-c
}
int main()
{
int a=2,b=3;
float d=5,e=7;
swap(&a,&b,sizeof(int));
swap(&d,&e,sizeof(float));
printf("%d %d %.0f %.0f\n",a,b,d,e);
return 0;
}
We all know that the C typesystem is basically crap, but try to not do that... You still have some options to deal with generic types: unions and opaque pointers.
Anyway, if a generic function is taking a void pointer as a parameter, it shouldn't try to dereference it!.