void test(void *a)
{
int *h = a; //error
}
int main(int argc, char const* argv[])
{
int z = 13;
test(&z);
return 0;
}
If I want to keep the void *a for test function, how can I get error line working?
I am able to compile and run the following with gcc without warning or error:
#include <stdio.h>
void test(void *a)
{
int *h = a;
printf("test: %d\n", *h);
}
int main(int argc, char const* argv[])
{
int z = 13;
test(&z);
return 0;
}
The only conceivable reason you would be getting an error on the line you indicated is that you are using a C++ compiler (g++ maybe?). If I try that I get the following error:
error: invalid conversion from ‘void*’ to ‘int*’
If you need to use a C++ compiler, you need to explicitly cast a to an int *:
int *h = (int *) a;
That one change allows this code to compile with g++ as well.
Related
Sorry to bother with this small issue for some but I am having trouble with calling the insertionsort function.
The professor said that the return value is either going to be just 0 or 1. 1 for success and 0 for failure. I just have to sort the linked list with tokens from the file. I am just doing a test of how I can implement this function because this function is the most important thing for the project.
This is what the professor is going to run and wants to see. -I for insertionsort and -q for quicksort during compile time:
./fileSort -i ./somefile
If "./somefile" contains:
hi,there, every, one
then output should be:
every hi one there
So I need to call two functions:
int insertionsort(void *toSort, int (*cmp)(void*, void*));
int quicksort(void *toSort, int (*cmp)(void*, void*));
but so far I am trying to get one done and I am very frustrated. Any help will be great.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define BUFSIZE 8
int compare(void *, void *);
void toSort(char *, int, int (*cmp)(void*, void*));
void swap(char *, char *);
void print_array (char **, int );
// int insertionsort(void *toSort, int (*comparator)(void*, void*));
int main(int argc, char const *argv[])
{
int insertionsort(void *toSort, int (*cmp)(void*, void*));
//build an array
char *array[BUFSIZE] = {"a", "b", "c", "d", "e", "f", "\0"};
int n = sizeof(array)/sizeof(array[0]);
if(n == -1)
{
printf("Error getting the size of the array\n");
}
printf("Size of the array: %d\n", n);
printf("Sorting the array.\n");
insertionsort(toSort, compare);
print_array(array, n);
printf("\n");
return 0;
}
int compare( void * a, void * b)
{
int val1 = *(int*)a;
int val2 = *(int*)b;
return ( val1 - val2 );
}
void toSort(char *array, int size, int (*cmp)(void*, void*))
{
int i, j;
for ( i = 1; i < size; i++ )
{
j = i;
while ( j > 0 && cmp( (char*)array+j-1, (char*)array+j ) > 0 )
// ^^^ call of cmp instead of operator >
{
swap( (char*)array+j-1, (char*)array+j);
j--;
}
}
}
void swap(char *a, char *b)
{
char *temp;
temp = a;
a = b;
b = temp;
}
void print_array (char **array, int size)
{
int i;
for (i = 0; i < size; i++) {
printf ("%d: %s\n", i, array[i]);
}
}
This is causing a compile error:
Undefined symbols for architecture x86_64:
"_insertionsort", referenced from:
_main in funcPointer-3f472a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The error message is a linker error telling you that during build there was no implementation found for the function you are trying to call.
The fact that the prototype is seen directly in the shown code (and some other hints) make me assume that it is you who is supposed to actually implement that function.
So, to solve the error you have quoted you can simply include the following at the place where you have a comment which shows the prototype for the missing function:
// prototype, to tell the compiler about the existence of this function
int insertionsort(void *toSort, int (*comparator)(void*, void*));
// implementation of that function
// (the separation is not really needed but a recommended practice,
// to prepare for later work with multiple code files
int insertionsort(void *toSort, int (*comparator)(void*, void*))
{
/* empty, the point of this code is only to get rid of the linker error,
to be filled in by you, implementation according to what you learned
in class about sorting
*/
return 0; // to match the prototype with return value int
/* find out about this return value,
i.e. how the function is supposed to be used and what it should return
*/
}
I'm new to C and wrote the following code that returns a char.
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
char test(){
char c = 'z';
return c;
}
But I get the following error when compiling:
read.c:8:1: warning: data definition has no type or storage class [enabled by default]
test();
^
read.c:71:6: error: conflicting types for ‘test’
char test(){
^
read.c:8:1: note: previous declaration of ‘test’ was here
test();
^
Any ideas? Does this require memory allocation? If so, why?
It is because you either have to define the function prototype above the main, or move the function above the main.
char test();
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
char test(){
char c = 'z';
return c;
}
or
char test(){
char c = 'z';
return c;
}
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
You haven't provided a prototype for test() function by the time you call it in main(). Either do char test(void); at the top of your source file (or more conventionally in a header file).
Other option is to move the definition of test() above main() function which would the ensure the definition itself provides the prototype.
The reason for the error:
error: conflicting types for ‘test’
is that in pre-C99 C, compiler implicitly provides an int returning prototype for test() (known as implicit int rule) which conflicts with the actual definition of test() (where it actually has char as return type). Note that this is no longer valid (in C99 and later).
In C the compiler start "reading" the code from the top to the bottom, so when it's on your main function trying to figure out what is test() it don't know this function yet.
To solve it you can put your main funcion after the test() function, or use function prototype wich is better code practice, manly for future readings of the code. Like this:
char test();
int main(int argc, char * argv[]){
char c = test();
printf("num = %c \n", c);
}
char test(){
char c = 'z';
return c;
}
Before using the name test in this statement
char c = test();
it must be declared.
And this message
read.c:8:1: warning: data definition has no type or storage class [enabled by default]
test();
^
says that the compiler does not know the type of the expression test() used in the declaration of the variable c as an initializer.
For compatibility with old versions of the C Standard the compiler assumes that the function has the return type int. However then it encounters that the function has the return type char. And these compiler messages say about this
read.c:71:6: error: conflicting types for ‘test’
char test(){
^
read.c:8:1: note: previous declaration of ‘test’ was here
test();
^
So before using the function you have to declare it
char test( void );
Pay attention to that the parameters of the function main
int main(int argc, char * argv[]){
are not used. So the function main could be declared like
int main( void ){
So the program can look like
#include <stdio.h>
char test( void );
int main( void )
{
char c = test();
printf( "num = %c\n", c );
return 0;
}
char test( void )
{
char c = 'z';
return c;
}
You are calling test before it's declared. Either declare it before the main function, or provide its prototype:
/* Prototype of test */
char test();
int main(int argc, char * argv[]) {
char c = test();
printf("num = %c \n", c);
}
char test() {
char c = 'z';
return c;
}
I just can't figure out how to pass an Argument like in the following scenario:
#include<stdio.h>
void quit(const char*);
int main(void){
const char *exit = "GoodBye";
void (*fptr)(const char*) = quit;
(*fptr)(exit);
return 0;
}
void quit(const char *s){
printf("\n\t%s\n",s);
}
This is how my program should work and it does, but when I make a text menu i just can't figure out how to do it:
#include<stdio.h>
#include<stdlib.h>
int update(void);
int upgrade(void);
int quit(void);
void show(const char *question, const char **options, int (**actions)(void), int length);
int main(void){
const char *question = "Choose Menu\n";
const char *options[3] = {"Update", "Upgrade", "Quit"};
int (*actions[3])(void) = {update,upgrade,quit};
show(question,options,actions,3);
return 0;
}
int update(void){
printf("\n\tUpdating...\n");
return 1;
}
int upgrade(void){
printf("\n\tUpgrade...\n");
return 1;
}
int quit(void){
printf("\n\tQuit...\n");
return 0;
}
void show(const char *question, const char **options, int (**actions)(void), int length){
int choose = 0, repeat = 1;
int (*act)(void);
do{
printf("\n\t %s \n",question);
for(int i=0;i<length;i++){
printf("%d. %s\n",(i+1),options[i]);
}
printf("\nPlease choose an Option: ");
if((scanf("%d",&choose)) != 1){
printf("Error\n");
}
act = actions[choose-1];
repeat = act();
if(act==0){
repeat = 0;
}
}while(repeat == 1);
}
Here I need to change the quit function (int quit(void); to int quit(char *s){};) like in the First example and call it with an argument like const char *exit = "GoodBye"; ==>> (*fptr)(exit);
I know that at this point my program takes only void as argument, but I done it only to illustrate the problem.
I'm very confused about this.
EDIT:
this int (*actions[3])(void) I think is an Array of Function pointers and all 3 function pointers takes void as argument, but I need to know if i can use one pointer to take an argument or i have to re-code the whole program.
Since you have an array of function pointers, all the functions need to be of the same type. So at the very least each function should take a const char * (not all functions need to use it) and the array type should be changed to match.
If you want something more flexible, you can have the functions accept a single void * so each function can be passed a different parameter which it then casts to the appropriate type. This is how pthreads passes parameters to functions which start a new thread. You will lose some compile-time type checking with this, so be careful if you go this route.
EDIT:
An example of the latter:
#include<stdio.h>
#include<stdlib.h>
int update(void *);
int upgrade(void *);
int quit(void *);
int main(void){
const char *question = "Choose Menu\n";
const char *options[3] = {"Update", "Upgrade", "Quit"};
int (*actions[3])(void *) = {update,upgrade,quit};
show(question,options,actions,3);
return 0;
}
int update(void *unused){
printf("\n\tUpdating...\n");
return 1;
}
int upgrade(void *unused){
printf("\n\tUpgrade...\n");
return 1;
}
int quit(void *message){
printf("\n\tQuit...%s\n", (char *)message);
return 0;
}
void show(const char *question, const char **options, int (**actions)(void *), int length){
...
if (act == quit) {
repeat = act("GoodBye");
} else {
repeat = act(NULL);
}
...
}
Since you are using a an array of function pointers, you don't know which ones to take which arguments. But have You can avoid re-coding it by making the functions to take "unspecified number of arguments". i.e. Remove the void from as the parameter from function definitions and prototypes from of the function pointers and from the quit() function.
int quit(const char*);
void show(const char *question, const char **options, int (**actions)(), int length);
int main(void){
const char *question = "Choose Menu\n";
const char *options[3] = {"Update", "Upgrade", "Quit"};
int (*actions[3])() = {update,upgrade,quit};
...
}
int quit(const char *msg){
printf("\n\tQuit...%s\n", msg);
return 0;
}
void show(const char *question, const char **options, int (**actions)(), int length){
....
int (*act)();
....
}
This works because C allows a function with no explicit parameters to take "unspecified number of arguments". Otherwise, you need to make all functions have similar signatures.
This procedure should convert a string that contains a set of double numbers separated by comma (e.g. 7.2,9.5,-5.515) to a vector of double type.
void ToDoubleVec(int d,const char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
Here is the snippet of program that calls it:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc,char** argv)
{
...
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
...
}
Debugger's output:
40 lower = malloc(dim*sizeof(double));
(gdb) s
42 ToDoubleVec(dim,argv[2],lower);
(gdb) s
ToDoubleVec (d=2, commaSeparated=0x7fffffffe9d3 "2.3,-62.1", result=0x603010) at testPSO.c:11
11 result[0]=atof(strtok(commaSeparated,","));
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff77f56bb in ?? () from /lib/x86_64-linux-gnu/libc.so.6
Why doesn't it work? I was sure that I've allocated enough memory for the array and also parameters seems to be passed correctly.
You can reduce your code to this SSCCE (Short, Self-Contained, Correct Example), which crashes nicely when you leave out #include <string.h> and does not compile cleanly when you add #include <string.h>:
segv.c: In function ‘ToDoubleVec’:
segv.c:8:5: warning: implicit declaration of function ‘strtok’ [-Wimplicit-function-declaration]
segv.c:8:20: warning: initialization makes pointer from integer without a cast [enabled by default]
segv.c:14:20: warning: assignment makes pointer from integer without a cast [enabled by default]
Code:
#include <stdlib.h>
//#include <string.h>
static void ToDoubleVec(int d, const char* commaSeparated, double *result)
{
int i;
result[0] = atof(strtok(commaSeparated, ","));
for (i = 1; i < d; i++)
result[i] = atof(strtok(NULL, ","));
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
ToDoubleVec(dim, arg, lower);
}
Passing the return value from a function such as strtok() which can return a null pointer directly to a function such as atof() which does not tolerate null pointers is foolhardy; it leads to crashes. If everything is correct, you'll be OK; if not, you'll crash and burn.
The unchecked memory allocation is a similar problem; you didn't even check that dim was non-zero (and non-negative) before doing the memory allocation in the original.
#include <assert.h>
#include <string.h>
#include <stdlib.h>
static void ToDoubleVec(int d, char *commaSeparated, double *result)
{
int i;
char *number = strtok(commaSeparated, ",");
if (number != 0)
{
result[0] = atof(number);
for (i = 1; i < d; i++)
{
number = strtok(NULL, ",");
if (number != 0)
result[i] = atof(number);
}
}
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
assert(lower != 0);
ToDoubleVec(dim, arg, lower);
}
You could — and in one version of the code I did — add error printing to report if the tests on number failed. But the crash is caused by the implicit declaration of strtok() as returning int and not char *.
I have tried to compile your code, and the compiler warned me that strtok() takes as input a char* and not a const char*. Then I have tried this code, and it is working correctly:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void ToDoubleVec(int d, char* commaSeparated,double *result);
int main(int argc,char** argv)
{
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
for (i=0; i<dim; ++i) {
printf("%f\n", lower[i]);
}
return 0;
}
void ToDoubleVec(int d, char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
So try to change const char* to char*, and check the input you pass to your program, maybe it is not correct and this could be the problem.
I have this code:
void PrintMainParameters(int n, char* array[])
{
int i = 0;
for(i = 0; i < n; i++)
{
printf("%s \n", array[i]);
}
}
int main(int argc, char* argv[] )
{
PrintMainParameters(argc, argv);
}
Works fine. Now I want to write PrintMainParameters as prototype to declare the function later in the source file.
I tried this one, but it says type mismatch, that the second parameter is an incompatible pointer type. I understand the compiler error, but I do not know why it occurs.
void PrintMainParameters(int, char*);
int main(int argc, char* argv[] )
{
PrintMainParameters(argc, argv);
}
void PrintMainParameters(int n, char* array[])
{
int i = 0;
for(i = 0; i < n; i++)
{
printf("%s \n", array[i]);
}
}
How must the prototype look like? Why does my code not work?
Your function takes an array of char pointers. Your prototype declares it to take a single char pointer instead. The correct prototype looks like this:
void PrintMainParameters(int, char*[]);
You can use either:
void PrintMainParameters(int, char**);
or:
void PrintMainParameters(int, char *[]);
Or if you prefer, you can insert a dummy parameter into the prototype, such as:
void PrintMainParameters(int argc, char *argv[]);