Reputation: 6187
I was testing an implementation of a comparator function. So here's my code that worked
#include <stdio.h>
#include <string.h>
int compare_names(const void* a, const void* b)
{
char* sa = (char*) a;
char* sb = (char*) b;
return strcmp(sa, sb);
}
int main()
{
char *a = "Bianca";
char *b = "Ana";
printf("Comparing %s with %s returns: %i\n", a, b, compare_names(a, b));
return 0;
}
But I don't think it's right as a
and b
arguments at compare_names
function should turn out to be a pointer to a pointer of char. As pointed in a book I've read, the correct code for the compare_names
function would be
int compare_names(const void* a, const void* b)
{
char** sa = (char**) a;
char** sb = (char**) b;
return strcmp(*sa, *sb);
}
But when I ran the code I got a segmentation fault (core dumped).
What am I missing here?
EDIT: I'm using gcc on Linux x64.
Upvotes: 1
Views: 192
Reputation: 663
Both versions should work, however, for the second version of the "campare_names" function, you should pass an aditional pointer to each of the char pointers when calling the function.
However your version of the function is correct, it only makes sence to use double pointer parameters, when you are expecting that a function wil alter the pointer position or data being pointed. In this case, since the strcmp function only reads the char* data and doesn't make any changes to it, you don't need an aditional pointer.
Upvotes: 0
Reputation:
You are passing char* arguments, not char** arguments. The example code you posted showing char** does the following:
1. Change generic pointer to a pointer to a string.
2. Compare the strings by dereferencing the char** arguments, meaning you're passing char* arguments to strcmp and return the result.
But you passed char* arguments to your comparison function, so the dereferencing ends up passing arguments of type char to strcmp. Since it expects pointers, the char is interpreted as a memory address. Comparing "hello" to "bye" actually compares the string at address 0x67 to the string at address 0x62, which will segfault.
Pass &a and &b to your comparison function to make it not segfault.
Upvotes: 1
Reputation: 2992
char** sa = (char**) a;
This line says: "If you direference twice your sa
you will end up with a char
" The problem is that since your a
is a pointer to char you can not direference it twice. So the casting you are doing is generally wrong.
When casting, the compiler trys to interpret your *a
which is a char
as a pointer to char so when the conversion is performed your *sa
ends up being a BadPtr since it fails to convert from char
to char *
.
So in your strcmp()
you have two BadPtr.
Upvotes: 1
Reputation: 4411
#include <stdio.h>
#include <string.h>
int compare_names(const void* a, const void* b)
{
char** sa = (char**) a;
char** sb = (char**) b;
return strcmp(*sa, *sb);
}
int main()
{
char *a = "Bianca";
char *b = "Ana";
printf("Comparing %s with %s returns: %i\n", a, b, compare_names(&a, &b));
return 0;
}
Now it's ok. You have to put the address of a
and b
in the printf
parameters, since there are casted to char**
.
Upvotes: 1