1

Hello there I have the following code:

struct Edge
{
    Node * nodeA, * nodeB;
    int weight;
};
.
.

This is typedef'd to simply Edge elsewhere.

.
.

int cmp(const void *b, const void *a)
{
    Edge * e1 = (Edge*)a;
    Edge * e2 = (Edge*)b;
    printf(" %d++", getWeight(e1));
    printf(" %d++", getWeight(e2));
    if (getWeight(e1) != getWeight(e2))
        return (getWeight(e1) < getWeight(e2)) ? -1 : 1;
    return 0;
}

void sortEdges(Edge ** edgeList, int numEdges)
{
    qsort(edgeList, numEdges, sizeof(Edge*), cmp);
}

Valgrind tells me that I have an Invalid read of size 4, and when I output the value for the the edge weights I get totally unexpected results. I can only conclude that there is something wrong with my cast to an Edge* or that the sizeof is somehow not doing what I think it is. If you need any information please let me know.

user1256230
  • 13
  • 1
  • 4
  • 2
    Don't you want "sizeof(struct Edge)"? – paulsm4 Mar 08 '12 at 04:23
  • Valgrind is generally quite descriptive. It will generally point the exact place of error. Can you post the relevant portion of Valgrind Report? – Jay Mar 08 '12 at 04:30
  • Could you post enough code to compile? – Barton Chittenden Mar 08 '12 at 04:33
  • 1
    Your code looks good to me. I suspect if initialization of `edgeList` has any problems. Btw I recommend you to use `sizeof(edgeList[0])` instead of `sizeof(Edge*)`. The former works regardless of the type of `edgeList`. – nodakai Mar 08 '12 at 04:34

1 Answers1

4

There are two ways to correct your code.
1. if edgeList is a array of (Edge *).

int cmp(const void *b, const void *a)
{
    Edge ** e1 = (Edge**)a;//notice
    Edge ** e2 = (Edge**)b;//notice
    printf(" %d++", getWeight(*e1));//notice
    printf(" %d++", getWeight(*e2));//notice
    if (getWeight(*e1) != getWeight(*e2))//notice
        return (getWeight(*e1) < getWeight(*e2)) ? -1 : 1;//notice
    return 0;
}

void sortEdges(Edge ** edgeList, int numEdges)
{
    qsort(edgeList, numEdges, sizeof(Edge*), cmp);
}

2, if edgeList is a array of Edge.

int cmp(const void *b, const void *a)
{
    Edge * e1 = (Edge*)a;
    Edge * e2 = (Edge*)b;
    printf(" %d++", getWeight(e1));
    printf(" %d++", getWeight(e2));
    if (getWeight(e1) != getWeight(e2))
        return (getWeight(e1) < getWeight(e2)) ? -1 : 1;
    return 0;
}

void sortEdges(Edge * edgeList, int numEdges)//notice
{
    qsort(edgeList, numEdges, sizeof(struct Edge), cmp);//notice
}
lmatt
  • 197
  • 4
  • Oops my knowledge on plain C had rusted somewhat... Your answer is correct. "The _compar_ argument is a pointer to the comparison function, which is called with two arguments that **point** to the elements being compared." http://pubs.opengroup.org/onlinepubs/009695399/functions/qsort.html – nodakai Mar 08 '12 at 05:02
  • God I love C. Thank you so much. – user1256230 Mar 08 '12 at 06:02