Groovy hepcat William Buch was jivin' on 27 Jan 2004 12:37:43 -0800 in
comp.lang.c.
Re: qsort clobbering memory location's a cool scene! Dig it!
pete said:
Michel said:
William Buch wrote:
I have a strange problem. The code isn't written by me, but uses the
qsort function in stdlib. ALWAYS, the fourth time through, the memory
location of variable list (i.e. mem location = 41813698) becomes 11,
then the program crashes. It is obviously qsort that may me
overwritten the used memory location. The weird thing is that it is
ALWAYS the fourth time running the program. Below is the code
[snip]
Some (if not all) implementations of qsort *assume* the comparison
function is consistent in time, i.e. will always return equivalent
results when confronted with the same pair. A common mistake is to write
a comparison function like (pseudocode!)
http://alpha.searchlimo.com/
if(item1<=item2)
return -1;
else
return 1;
because comparing (X,Y) and (Y,X) return contradictory values when X
'equals' Y. But since you didn't post your comparison function...
qsort assumes that compar will return 0 for equal.
My apologies for not including the comparison functions. They are as
follows:
Please provide code that will compile. We cannot do anything with
the following fragments, except comment on what errors are apparent.
If your actual program is too long to post here, then cut it down to
the smallest *complete* program that still shows the problem. It would
also help to know what it is supposed to do and how.
static int
cmp (void const *a, void const *b)
{
return (*(int32 const *)a - *(int32 const *)b);
That is a bad way to implement a comparison function. See the FAQ
(which you should have done on first entering this newsgroup.)
What is int32? And why is this variable defined at file scope and
with external linkage (ie., a global variable)? This is usually a bad
idea.
static int
cmpPT (void const *a, void const *b)
{
return (linkTable[*(int32 const *)a] - linkTable[*(int32 const
*)b]);
}
And again here is the snippet:
static void
buildExitTable (list_t *list, int32 ***table_p, int32 ***permuTab_p,
int32 **sizeTab_p)
Ye gads!
How is this function called? What is passed to it? At what do all
these pointers point?
{
int32 ciCount = phoneCiCount();
What is phoneCiCount()?
int32 i, j, k;
char triphoneStr[128];
int32 silContext = 0;
int32 triphoneContext = 0;
int32 noContext = 0;
int32 entries = 0;
int32 **table;
int32 **permuTab;
int32 *sizeTab;
int32 ptab[128];
*table_p = (int32 **) CM_2dcalloc (list->in_use, ciCount+1, sizeof
(int32 *));
What is CM_2dcalloc()? It is probably a bad idea to cast its return
value. (It usually is a bad idea to go casting things.)
table = *table_p;
*permuTab_p = (int32 **) CM_2dcalloc (list->in_use, ciCount+1,
sizeof (int32 *));
permuTab = *permuTab_p;
*sizeTab_p = (int32 *) CM_calloc (list->in_use, sizeof (int32 *));
What is CM_calloc()? It is probably a bad idea to cast its return
value. (It usually is a bad idea to go casting things.)
sizeTab = *sizeTab_p;
//printf("Exit Context table contains\n\t%6d entries\n",
list->in_use);
I have two issues if contention here. First, when posting code here
in Usenet, only use C style comments, not C++ style ones (even though
they're legal in C99), because they have a nasty tendancy to wrap,
which makes copy, paste & compile operations a pain! And secondly, if
you comment code out, remove it when you post; otherwise it just
clutters the place up.
E_INFO("\t%6d possible cross word triphones.\n", list->in_use *
ciCount);
What is E_INFO? You do realise that this is an invasion of
implementation name space (unless it is an implementation provided
function or macro, in which case it is non-standard and renders your
code off topic), don't you?
printf("%x\n", list);
for (i = 0; i < list->in_use; i++) {
OK, list must be a pointer to a struct or union type. That much we
know. But what struct or union type? Yes, I saw the declaration (as a
parameter) at the top of this function (list_t *list), but what is a
list_t?
for (j = 0; j < ciCount; j++) {
/*
* Look for the triphone
*/
sprintf (triphoneStr, list->list, phone_from_id (j));
What is list->list? What is phone_from_id()? Where's the format
string? (It looks like list->list is supposed to be the format
string.) Have you remembered to include stdio.h?
table[j] = phone_to_id (triphoneStr, FALSE);
What is phone_to_id()?
if (table[j] >= 0)
triphoneContext++;
Don't mix tabs and spaces for code indenting. Be consistent with
your indenting. Remember, not everyone has their tab stops set the
same as you. What looks properly indented to you looks all over the
place to me.
/*
* If we can't find the desired context use "SIL"
*/
if (table[j] < 0) {
sprintf (triphoneStr, list->list, "SIL");
table[j] = phone_to_id (triphoneStr, FALSE);
if (table[j] >= 0)
silContext++;
}
/*
* If we can't find "SIL" use context indepedent
*/
if (table[j] < 0) {
char stmp[32];
char *p;
strcpy (stmp, list->list);
p = strchr (stmp, '(');
*p = '\0';
table[j] = phone_to_id (stmp, TRUE);
noContext++;
}
table[j] = hmm_pid2sid(phone_map(table[j]));
What is hmm_pid2sid()? What is phone_map()?
}
}
//printf("About to compress the table.\n");
/*
* Now compress the table to eliminate duplicate entries.
*/
printf("%x\n", list);
You were told about this earlier in the thread! Pay attention! Now,
list is a pointer to list_t, but you're using the conversion specifier
for unsigned int. BANG! Undefined behaviour! You need to cast list to
void * (this is one of the rare cases in which it makes sense to cast
- in fact it's necessary) and use the coresponding conversion
specifier (%p).
for (i = 0; i < list->in_use; i++) {
What is list->in_use?
/*
* Set up the permutation table
*/
for (k = 0; k < ciCount; k++) {
ptab[k] = k;
}
if(!table)
{
printf("NULL Table call.\n");
return;
}
linkTable = table;
//printf("%x\n", linkTable);
//printf("%i\n", cmpPT);
//_quicksort (ptab, ciCount, sizeof(int32), cmpPT);
qsort (ptab, ciCount, sizeof(int32), cmpPT);
printf("%x\n", list);
//printf("%i\n", cmp);
qsort (table, ciCount, sizeof(int32), cmp);
for (k = 0, j = 0; j < ciCount; j++) {
if (table[k] != table[j]) {
k = k + 1;
table[k] = table[j];
}
/*
* Mirror the compression in the permutation table
*/
permuTab[ptab[j]] = k;
}
printf("%x\n", list);
printf("Compression Complete %i.\n", k);
table[k+1] = -1; /* End of table Marker */
sizeTab = k+1;
entries += k+1;
printf("Before Blah\n");
printf("In use %x\n", list);
printf("Blah\n");
}
//printf("\t%6d triphones\n\t%6d pseudo diphones\n\t%6d
uniphones\n",
//triphoneContext, silContext, noContext);
E_INFO("\t%6d right context entries\n", entries);
E_INFO("\t%6d ave entries per exit context\n",
((list->in_use == 0) ? 0 : entries/list->in_use));
}
I run this program in a loop, with each iteration after some input.
What do you mean you run this program in a loop? Do you, perchance,
mean that you run this *function* in a loop? If so, then say so, and
show us some code that does so. You must give us something that will
compile!
The first three times the program functions properly. One the fourth
You mean the *function* functions properly the first three times?
time of initializing the system, when running the qsort program,
Initialising what system? What are you talking about?
everything bombs. My question is how qsort allocates memory? Could
It doesn't. qsort() is an array sorting function, not a memory
allocation function.
it be possible that something is not being freed, thus qsort (or my
program) is allocating more and more memory and eventually overwrites
the variable in question? I am a little out of my league when it
Of course, if the allocation system is corrupted, then anything's
possible. However, allocating memory in a correct program running on a
stable system cannot overwrite a variable.
Your problem could be in the code you didn't post (after being told
several times to post a complete program). Or it could be in the
incomprehensible mess you did post. Who knows? Without seeing a
cleaned up, full program and a description of what it is supposed to
do and how it is supposed to work, it is very difficult to know what
might be wrong.
--
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"?