Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using qsort() on a dynamically allocated 2d array

Status
Not open for further replies.

zanza

Programmer
Feb 18, 2002
89
US
so, we want our polynomials in the "proper" order (descending exponents) right? of course. :) or so my algebra 2 book says. *shrug*

anyway, to do that i have a dynamically alloced 2d array holding each of the terms of the polynomial as a character string. currently, im attempting this to sort them:

qsort((void *)TermArray, NumberOfTerms, sizeof(char *), compare);
...
int compare(const void *a, const void *b )
{
char *str1 = (char *) a, *str2 = (char *) b;
int len1 = strlen(str1), len2 = strlen(str2);
int i = 0, exp1 = 0, exp2 = 0;

for(i = 0; i < len1; i++)
{
if(str1 == '^')
exp1 = i;
}

for(i = 0; i < len2; i++)
{
if(str2 == '^')
exp2 = i;
}

len1 -= exp1;
len2 -= exp2;

exp1 = atoi(str1+len1);
exp2 = atoi(str2+len2);

if(exp1 < exp2)
return -1;
if(exp1 > exp2)
return 1;
else
return 0;
}

that _should_ scan until it hits the exponent, convert the exponent to an int, compare, and return properly (i think). but it doesnt. qsort isnt quite passing the correct values. anyone care to point out my silly error? (this is the first time ive tried sorting a 2d array, so i know itll be obvious to someone smarter than i)

žÅNžÅ
 
> anyway, to do that i have a dynamically alloced 2d array holding each of the terms
Exactly how did you do this?
There are a couple of possibilies, and you need to match your compare function to the one you choose.

In general, T is some type
Code:
T array[somesize];
T *parray = malloc( somesize * sizeof *parray );

qsort( array, somesize, sizeof(T), compare );
qsort( parray, somesize, sizeof(T), compare );

int compare ( const void *a, const void *b ) {
  const T* pa = (const T*)a;
  const T* pb = (const T*)b;
  // compare whatever *pa and *pb point at
}

--
 
i place the polynomial in a string, and then split it up into its respective terms thusly...

char **sort;
int los = 0, i = 0, not = 0, lot = 0, ct = 0, lopt = 0;
...
//(after having counted the number of terms)...
sort = (char **) malloc((sizeof(char)*not));

for(i = 0; i < los; i++) //loop to "length of string"
{
if(terms == '+' || terms == '-')
{
if(i) //make sure the operand is not the first character
{
lot = i - lopt; //length of term = current position - length of previous terms
//allocate the 2nd dimension to hold the term
sort[ct] = (char *) malloc((sizeof(char)*lot+1));
memcpy(sort[ct], terms+lopt, lot);
sort[ct][lot] = '\0';
//length of previous terms = current position
lopt = i;
//current term++
ct++;
}
}
//special case for the last term (because theres no operand after it, etc etc
if(ct == not-1)
{
lot = los - i;

sort[ct] = (char *) malloc((sizeof(char)*lot+1));
memcpy(sort[ct], terms+lopt, lot);
sort[ct][lot] = '\0';

lopt = i;
ct++;
}
}

and im sorry if i forgot something, but i think that should be all thats needed...? ^_^;;

žÅNžÅ
 
> sort = (char **) malloc((sizeof(char)*not));
This is short of memory. You should be allocating sizeof(char*), not sizeof(char). In a typical 32 bit environment, a char* is 4 times bigger than a char.

You're also casting the return result of malloc, which is generally a bad idea in ANSI-C. At worst, you mask a serious problem if you fail to include stdlib.h

This is what the malloc call should look like.
[tt]sort = malloc( not * sizeof *sort );[/tt]

Try following your code with
Code:
for ( i = 0 ; i < not ; i++ ) {
  printf( "%d %s\n", i, sort[i] );
}
to make sure everything looks OK

--
 
my apologies, i apparently mistyped or miscopied my own code. -_-

sort[ct] = (char *) malloc((sizeof(char)*lot+1));

is the actual line that im using, and that indeed works. when i finished that part of the code, i made sure it worked just as you said, salem (with the for loop). but, as i said, the problem is that qsort isnt sending the correct data to the comparison function.

and, here is the _entire_ and actual source file, all happily up to date...
žÅNžÅ
 
... *smacks his own forehead*

nevermind that entire post... i misunderstood you salem. let me try that. :)

žÅNžÅ
 
alright, i changed the string/pointer allocation, and it still doesnt work.

once more, ive uploaded the up to date source (see above).

and, once more, the allocation works, but qsort isnt.

žÅNžÅ
 
Read my earlier post - the converted types in your compare function are wrong.

You malloc an initial array of type char**, which makes 'T' a char*.
In the qsort compare funtion, this means that the input parameters are T* (or char**).
These need to be dereferenced back down to char* before you can use the standard string functions on them.

Code:
int compare(const void *a, const void *b )
{
    char **pstr1 = (char**)a, **pstr2 = (char**)b
    char *str1 = *pstr1, *str2 = *pstr2;
    // rest of your code

Some FAQs you should read
gets()
fflush(stdin)

--
 
so ka. danke. :)

that entire faq is very useful, ill be sure to read it.

žÅNžÅ
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top