The code is the following. The reason I'm using void * args is because this function has to be used in a threaded program. It was tested with and without any threads, and it doesn't work in any of both workflows. I'm pretty new to C and this might be obvious to the average programmer but even with gdb I can't find the problem.
void arg(const void* args) {
char* arr = (char*) args;
printf("%s", arr[0]);
printf("%s", arr[1]);
return;
}
int main (void) {
char* a[2] = {"Hello", "World!"};
arg((void*)a);
return 0;
}
The above code will segfault when dereferencing args.
CodePudding user response:
First things first, char* a[2] = {"Hello", "World!"}; is not valid C . If you enable warnings you'll see that we need to declare a as
vvvvv----------------------------------->added const
const char* a[2] = {"Hello", "World!"}; //VALID
Also there is no need to cast anything to void* here. You can directly declare the parameter to be of type const char** as shown below:
void arg(const char** args) {
std::cout<<args[0]<<std::endl;
std::cout<<args[1]<<std::endl;
return;
}
int main () {
const char* a[2] = {"Hello", "World!"};
arg(a);
return 0;
}
Another option is to use std::string instead of string literals here.
The reason I'm using
void * argsis because this function has to be used in a threaded program
void arg(const void* args) {
const char*const* ptr = static_cast<const char * const *>( args );
std::cout<<ptr[0]<<std::endl;
std::cout<<ptr[1]<<std::endl;
return;
}
int main () {
//--vvvvv------------------------------------>added const
const char* a[2] = {"Hello", "World!"};
//------v------------------------------------>no need to use cast here
arg(a);
return 0;
}
And the C version can look like:
void arg(void* args)
{
const char** arr = args;
printf("%s", arr[0]);
printf("%s", arr[1]);
}
CodePudding user response:
The expressions arr[0] and arr[1] have the type char after the casting
char* arr = (char*) args;
So at least using the conversion specifier s with objects of the type char
printf("%s", arr[0]);
printf("%s", arr[1]);
is incorrect.
It seems you mean the following
void arg(const void* args) {
const char** arr = args;
printf("%s", arr[0]);
printf("%s", arr[1]);
}
Pay attention to that the array a
char* a[2] = {"Hello", "World!"};
used in expressions (with rare exceptions) is implicitly converted to a pointer of the type char **.
In C the array of string literals shall be declared with the qualifier const
const char* a[2] = {"Hello", "World!"};
And you need explicitly casting the pointer of the type const void to the type const char ** like for example
const char*const* arr = static_cast<const char * const *>( args );
