Is there an easier way to work with pointers (sample code included)

  • Thread starter walter.preuninger
  • Start date
P

pete

David said:
[...]
int cmp(const void *i, const void *j)
{
return strcmp(i, j);
}

[...]
char *base[3];
base[0] = string0;
base[1] = string1;
base[2] = string2;
[...]
qsort(base, sizeof base / sizeof*base, sizeof*base, cmp);

Several people have posted code like this now, all apparently without
noticing that it's wrong.

base is an array of pointers to char. This is passed to qsort. qsort
calls cmp with two pointers, each of which points *to an element of
the array*.

Those void *'s in the argument of cmp are "really" char **,
not char *,
and passing them to strcmp produces undefined behavior.

It so happens that you (and the OP) have laid out the program so that
on most platforms strcmp will reach a zero byte somewhere before
faulting, and the conventional layout of automatic storage is such
that strcmp interpreting the addresses as strings will generate the
expected output sort order, so just running the program once to check
it is misleading.

I hate when that happens!
cmp needs to be

int cmp(const void *i0, const void *j0) {
const char *const *i = i0;
const char *const *j = j0;
return strcmp(*i, *j);
}

HTH.

Oops!
Good catch!
 
P

Peter Shaggy Haywood

Groovy hepcat Al Balmer was jivin' on Wed, 08 Mar 2006 12:00:35 -0700
in comp.lang.c.
Re: Is there an easier way to work with pointers (sample code
included)'s a cool scene! Dig it!
int cmp(const void *i, const void *j)
{
char *s1 = i;
char *s2 = p;

return strcmp(s1, s2);
}

That won't do. The OP is dereferncing the pointers (s1 and s2). They
have type char **, not char *.
Also, you're discarding the const qualifier in the assignment.
That's not kosher without a cast.

----------------------------------------------------------------------
6.5.16.1 Simple assignment

Constraints
....
— one operand is a pointer to an object or incomplete type and the
other is a pointer to a qualified or unqualified version of void, and
the type pointed to by the left has all the qualifiers of the type
pointed to by the right;
----------------------------------------------------------------------

The type pointed to by the left operands (unqualified *s1, *s2) don't
have all the qualifiers of that pointed to by the right (const
qualified *i, *j).
And the strings being sorted or searched (I'm assuming this is a
comparison function a pointer to which is to be passed to bsearch() or
qsort() function) should really be treated as const qualified (ie.,
should *be* const qualified).
So, something like this would be in order:

#include <string.h>

int cmp(const void *i, const void *j)
{
const char *const *s1 = i;
const char *const *s2 = j;

return strcmp(*s1, *s2);
}

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
A

Al Balmer

That won't do. The OP is dereferncing the pointers (s1 and s2). They
have type char **, not char *.

That why I asked (you snipped) "Is that what you're trying to do?" The
OP's code indicated to me that he was rather confused. I picked
something I thought was more likely than what he actually wrote.
Also, you're discarding the const qualifier in the assignment.
That's not kosher without a cast.

Yes. Pointed out and acknowledged three days ago, in my very next
message.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top