I am trying to to run c code in c++ which uses clone inside , I got an error which I couldn't solve it , anyone used clone in c++ before , and can help .
my code:
int variable, fd;
using namespace std ;
int do_something() {
variable = 42;cout << "sana" << endl ;
close(fd);
_exit(0);
}
int main() {
void **child_stack;
char tempch;
variable = 9;
fd = open("test.file", O_RDONLY);
child_stack = (void **) malloc(16384);
printf("The variable was %d\n", variable);
clone(do_something, child_stack,CLONE_VM|CLONE_FILES, NULL);
sleep(1);
printf("The variable is now %d\n", variable);
if (read(fd, &tempch, 1) < 1) {
perror("File Read Error");
exit(1);
}
printf("We could read from the file\n");
return 0;
}
and i got the errors:
dell#ubuntu:~$ g++ n.cpp -o n
n.cpp: In function ‘int main()’:
n.cpp:40:62: error: invalid conversion from ‘int ()()’ to ‘int ()(void*)’ [-fpermissive]
/usr/include/x86_64-linux-gnu/bits/sched.h:83:12: error: initializing argument 1 of ‘int clone(int ()(void), void*, int, void*, ...)’ [-fpermissive]
dell#ubuntu:~$
Compiler is telling you that first argument to clone is supposed to be int(*)(void*) (a pointer to function taking one void* parameter and returning int) and that you're trying to pass it int(*)() (a pointer to function taking no parameters and returning int).
The former can't be implicitly converted to the latter, hence the error.
To fix it, you can define do_something as:
int do_something(void*)
{
// your code
}
You really should not use the clone(2) system call. It is (sort of) reserved -like futex(2)- to the implementation of pthreads. And C++11 standard practically requires that pthreads are linked into the compiled application.
If you want to use clone (which is a probable mistake), retrict yourself to C, and carefully avoid the pthread library to be needed, even indirectly; by your application.
If you insist on using clone, the child_stack argument to it should be suitably aligned (at least to a page of 4Kbytes), and malloc does not guarantee that. You might use mmap or posix_memalign.
But really, don't use clone (specially not from C++). Use pthreads.
Related
Getting error:
error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
on g++
on the following code:
void* func(void *s)
{
int i = 0;
int self = (int *)s;
printf("Thread Entered: %d\n", self);
sm.lock(self);
// Critical section (Only one thread
// can enter here at a time)
for (i=0; i<MAX; i++)
ans++;
sm.unlock(self);
}
You need to change int self = (int *)s; to int self = *((int *)s); or to int * self = (int *)s;.
You need to think of these as two different things. One is a pointer to memory where the value is stored (int*) and the other is an actual value (int).
Looking at your function declaration void* func(void *s), your s parameter is of type void, this will need to be int if you wish to convert it.
Your data types seem a bit mixed, which just doesn't fly do well in C/C++. Can you clean it? If you are using this function with pthread_create(), as per the documentation with example for this function, try..
// your pthread_create call..
int SOME_INT = 123;
s = pthread_create(&thread_id, &attr, &thread_start, &SOME_INT);
//...and your function
void* func(void *s)
{
int self = (int*) s;
Pointers can be confusing. See if that above code looks similar, in particular to passing the last parameter for pthread_create as a pointer reference. And then try your original code. It might just be that it wasn't passed as a reference.
See what that yields you, else try storing it as a pointer and then converting on use.
void* func(void *s)
{
int *self = s;
sm.lock(*self); // but can give a potential race condition.
In the second line of the function body, I suspect you were trying obtain the value at s (as an int pointer), but you actually cast it directly to an int. That would yield the address in s rather than the value stored there.
This code on array of structures is working but according to my understanding it shoudn't.
Code:
#include<stdio.h>
#include<string.h>
int main()
{
struct virus {
char signature[25];
char status[20];
int size;
} v[2] = {
"Yankee Doodle", "Deadly", 1813,
"Dark Avenger", "Killer", 1795
};
for(int i=0;i<=1;i++) {
printf("%s %s\n", &v[i].signature, &v[i].status);
}
return 0;
}
According to me, when we try to access the members of a structure using the address of an instance of the structure, we must use the -> operator rather than the . operator. I know that we do it only in case a pointer,but as far as I know, array is functionally equivalent to a pointer. Please help me where I am going wrong with my concepts. And pardon my silly question, because I am just a beginner.
It should not according to Operator Precedence. [] has higher precedence than ., and . has higher precedence than &. So &v[i].signature is equivalent to & ( (v[i]).signature). So first the ith item is taken from v, then it's signature member is accessed, which is a character array, and then & is applied which gives the address of the character array.
It works in VS, but this is not standard behavior.
It doesn't really work. You probably expected &v[i].signature to be (&v[i]).signature (which should have been (&v[i])->signature), but it's actually &(v[i].signature), of type char (*)[25]. If the program still produces the expected output, then that's purely by chance.
GCC would have told you this even without -Wall:
$ gcc -c a.c
a.c: In function ‘main’:
a.c:18:9: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[25]’ [-Wformat=]
printf("%s %s\n",&v[i].signature,&v[i].status);
^
a.c:18:9: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char (*)[20]’ [-Wformat=]
It's working because:
&v[i].signature == &v[i] == v->signature
(&v).signature == v->signature
You have taken the address using & and dereferenced using [].
I am trying (using pthread_create) to pass a value to the function:
void philosopher(int);
I only need a way to differentiate between each thread. It does not matter which order they run in (clearly, since they are threads), nor even which order they were created in, but they need to contain a least one difference so that I can tell the difference between them. The reason for this is that, in the function, each thread needs to refer to itself as "philosopher 1, philosopher 2,...". The number of philosophers is dynamic (the user passes it as an argument when running the program).
pthread_t threads[philo];
for (int i = 0; i < philo; i++)
pthread_create(&threads[i], NULL, &philosopher, reinterpret_cast<void*>(i));
I get an error from the above code: "invalid conversion from ‘void (*)(int)’ to ‘void* (*)(void*)’ [-fpermissive]. Clearly, I need to pass i by value (because i changes in the for loop). I am stuck at compile time, however, and have only ever been able to have my pthread programs compile when the last value was NULL. I have also tried:
pthread_create(&threads[i], NULL, &philosopher, i);
and
pthread_create(&threads[i], NULL, &philosopher, (void*)i);
both of which produce the same compiler errors.
You're having problem with a different parameter than you think - it's the thread function that's the problem.
It's supposed to take a void * - not an int - and return a void *, so change it to
void* philosopher(void*);
and inside the philosopher function, you cast the parameter back to an int.
(Don't cast the function - that's undefined.)
The error message is pretty clear. You need a function of type void * (void *), and you have a function of type void (int). Fix it:
extern "C"
void * philosopher(void * data)
{
uintptr_t n = reinterpret_cast<uintptr_t>(data);
// ...
return nullptr;
}
(As #Deduplicator mentioned, strictly speaking pthread_create requires that the thread function have C linkage, so in C++ you need to declare it as extern "C".)
for passing arguments, pthread requires void pointer. I want to pass two variables, int and long. To save myself some trouble, I will pass two long instead. So this is what I do:
int main(int argc, char *argv[])
{
/*SOCKET INIT*/
pthread_t socketTh;
long data[2] = {ip2l(IP),80};
pthread_create(&socketTh, 0, &serverConnect, (void*)data); //ERROR HERE
while(true) {
/*event loop*/
}
quit_thread(&sockerTh); //just an EXAMPLE! I don't know how to quit threads, I will google it later
return 0;
}
Error:
error: invalid conversion from 'void (*)(void*)' to 'void* (*)(void*)'
But it seems that this is not the correct way to retype long pointer to void pointer. I wonder not of threads Stackoverflow has suggested me didn't help, as well as any Google search. So maybe, try to explain it really slowly, because I'm beginner and I'm still lost in data types.
Thank you.
Update:
I create the unsigned long* in main(). This means this variable will last as long as the program itself.
The error message refers to the third argument. pthread_create wants a pointer to a function that takes a void* and returns void*. Apparently the function serverConnect is a function that takes a void* and returns void.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
void pointers: difference between C and C++
Hi I have the following function:
void task2(int a)
{
printf(" Task 2 running..\n");
sleep(2);
printf(" Task 2 exiting..\n");
}
thpool_add_work(threadpool, (void*)task2, (void*)a);
int thpool_add_work(thpool_t* tp_p, void *(*function_p)(void*), void* arg_p)
{
// some code here
}
The above code works well with C, but does not compile in C++. I'm getting the following error:
error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
error: initializing argument 2 of ‘int thpool_add_work(thpool_t*, void* (*)(void*), void*)’
I'm not able to figure out the reason for this error. Any idea why this error crops up when I change the file extension to CPP and compile?
You have to change the signature of task2 to match the type of the thpool_add_work argument:
void* task2(void* a)
The call which creates the thread would become
thpool_add_work(threadpool, task2, &a);
assuming that a is int.
If you need to use the argument of task2, you could do following:
int ia = *(int*)a;
Update to answer the OP comment
thpool_add_work expects a function with void* argument for a reason. In such a way, you can pass any kind of parameter into the thread function, albeit in a type-unsafe way.
You pass the address of the parameter converted to void* as the 3rd argument of thpool_add_work. Afterwards, you cast a pointer to void back to the pointer to your expected parameter type and dereference it to get the value of the parameter. I gave the example for int a above, now how it would look for a float:
void* test3(void* a)
{
float fa = *(float*)a;
.....
return NULL;
}
Try this
thpool_add_work(threadpool, (void* (*)(void*))task2, (void*)a);
C converts void* to any type automatically, C++ does not.
You could improve the code with a typedef
typedef void* (*worker_func_t)(void*);
thpool_add_work(threadpool, (worker_func_t)task2, (void*)a);
int thpool_add_work(thpool_t* tp_p, worker_func_t function_p, void* arg_p)
{
// some code here
}