0

So to try to sum this up nicely, I have a main struct that is a catalog, it contains a counter(of the books it has), the capacity(total number of books it can support, can also grow), and an array of pointers that point to another struct that contains the book information.


typedef struct BooksInStock{
    int id;
    char title[MAX_TITLE];  // 38 Characters
    char author[MAX_AUTHOR]; // 20 Characters
    double level;
    int words;
}Books;


typedef struct Stock {
    Books *b;
    int count;
    int capacity;
} Stock;

The exact valgrind error is:

==23844== Invalid read of size 4
==23844==    at 0x401418: idComp (catalog.c:27)
==23844==    by 0x4E6FC62: msort_with_tmp.part.0 (in /usr/lib64/libc-2.17.so)
==23844==    by 0x4E6FBD7: msort_with_tmp.part.0 (in /usr/lib64/libc-2.17.so)
==23844==    by 0x4E6FFB6: qsort_r (in /usr/lib64/libc-2.17.so)
==23844==    by 0x401AE3: listAll (catalog.c:168)
==23844==    by 0x400C13: main (reading.c:73)
==23844==  Address 0x6e61724674666172 is not stack'd, malloc'd or (recently) free'd

I am assuming this is because I am not allocating my structs/array properly, but I haven't had to dynamically allocate an array of structs inside another struct before and I believe I am confusing myself.

EDIT: I was allocating the memory wrong see: C printing extremely weird values with printf

EDIT: As pointed out I forgot the method that calls idComp

void listAll(Catalog *cat)
{ // cat is just the catalog of books that have been read in already
    qsort(cat->b, cat->count, sizeof( Books ), idComp);  // idComp is called here
    if (cat->count == 0) {
        printf("No matching books");
    } else {
        printf("%5s %38s %20s %5s %7s", "ID", "Title", "Author", "Level", "Words");
        for (int i = 0; i < cat->count; i++) {
            printf("%5d %38s %20s %5.1f %7d", cat->b[i].id, cat->b[i].title,
            cat->b[i].author, cat->b[i].level, cat->b[i].words);
        }
    }
    printf("\n");
}
4
  • You didn't disclose how levelComp is called. Please post a Minimal, Reproducible Example. Commented Oct 23, 2020 at 19:14
  • @MikeCAT unfortunately there is a limit on how much of this I can actually post, it is a school assignment I just came here because I haven't been able to get a response from my teacher in 2 days. Commented Oct 23, 2020 at 19:18
  • That's the comparator function for qsort()? Commented Oct 23, 2020 at 19:19
  • @WeatherVane yes it is, or at least it is supposed to be. Commented Oct 23, 2020 at 19:19

1 Answer 1

4

cat->b points at an array of Books, so what are passed to comparision function of qsort are pointers to Books, not pointers to pointers to Books.

Threfore, the idComp function should be like this:

static int idComp( const void *aptr, const void *bptr )
{
  const Books *a = aptr;
  const Books *b = bptr;

  if ( a->id < b->id )
    return -1;
  if ( a->id > b->id )
    return 1;
  return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.