1

table.h:

#ifndef table_h
#define table_h   

//  The object:
typedef struct Pair
{
    char* name;
    int number;
} Pair;

int comp_pair(const void* lhs, const void* rhs)
{
    Pair* lp = (Pair*) lhs;
    Pair* rp = (Pair*) rhs;

    const char* ln = lp->name;
    const char* rn = rp->name;

    return strcmp(ln, rn);
}

// The array and associated functions:
size_t table_capacity;                                           
size_t table_size;                                               
Pair* table;            // <------ Global variables -------------------

Pair* create_table (size_t capacity)
{
    Pair* p = 0;
    p = (Pair*) malloc(sizeof(*p) * capacity);

    if (p == NULL && capacity > 0)
    {
        perror("create_table()::bad allocation!\n");
        exit(-1);
    }

    table_capacity = capacity;

    return p;
}    

void insert (Pair* table, const char* name, int number)
{
    Pair* p = (Pair*) malloc(sizeof(*p));

    if (p == NULL)
    {
        perror("insert::bad allocation!\n");
        exit(-1);
    }

    p->name = name;
    p->number = number;

    table[table_size++] = *p;
}

void print_table(Pair p[], size_t size)
{
    size_t i = 0;
    for (i; i < size; ++i)
    {
        printf("%s -> %d\n", p[i].name, p[i].number);
    }
}

#endif

main.c:

#include <stdio.h>
#include <stdlib.h>     // qsort() 
#include <string.h>     // strcmp()
#include <stddef.h>     // size_t
#include "table.h"

int main()
{
    char* names [ ] = { "bla1", "bla2", "bla3", "bla4", "bla5"};
    int numbers [ ] = { 1, 2, 3, 4, 5 };
    size_t s = 5;
    size_t i = 0;

    table = create_table(s);

    for (i; i < s; ++i)
    {
        insert(table, names[i], numbers[i]);    
    }

    qsort(table, table_size, sizeof(Pair), comp_pair);

    print_table(table, table_size);
    getchar();

    free(table);
}

When I try to use qsort(), (debugging) the above code generates the following error:

Access violation reading location 0x65727541.

Questions:

  1. Is the function comp_pair() correct?
  2. What size should I pass as a third parameter in qsort(), the current sizeof(Pair) or the size of the actually compared types, i.e. char*?
Ziezi
  • 6,375
  • 3
  • 39
  • 49
  • 1
    cannot reproduce with the code shown. Although there ARE problems (like `const` correctness, a memory leak in `insert()` and a questionable design with a global for the size of something that's returned as an instance) -- the code should work as intended. Is there some code missing? –  Jun 16 '17 at 12:54
  • 3
    Not to real problem, but you have meory leak in `insert`. You allocate Pair, initialize it, copy contents to table, and then forget to free it. You don't need malloc for that, you can use next table index to initialize the pointer. – user694733 Jun 16 '17 at 12:54
  • 2
    Besides a memory leak in your insert() function, the code you posted here looks fine, as long as you have the proper `#include`s The issue is with something else, make sure your actual code matches the code you posted here. – nos Jun 16 '17 at 12:55
  • Thank you all for the remarks! This is all the code that I use, the only missing line is a `getchar()` at the end. I'll remove the allocation in `insert()` as suggested. – Ziezi Jun 16 '17 at 12:59
  • @nos code is absolutelly not ok. Not just leak in insert, but also no need for any malloc. And I got downvotes for correct answer. – unalignedmemoryaccess Jun 16 '17 at 13:00
  • 1
    The code in the question is not related to the error you get. I know this because the pointer you fault on is most likely a string that contains the characters "Atre" – Art Jun 16 '17 at 13:00
  • `p->name = name;` is not good plus the twice memory allocation. allocate name instead – P0W Jun 16 '17 at 13:00
  • *"This is all the code that I use"* As @nos said, if those snippets are on different files, then lack of `#include` could be a problem. Please create [mcve] and clarify your post. – user694733 Jun 16 '17 at 13:03
  • 1
    And enable compiler warnings. If it's just a missing `#include`, a decent compiler should emit a clear warning. –  Jun 16 '17 at 13:04
  • You misuse a `.h` file to contain code and variables (instead of just their declarations), but this still doesn't explain the problem.... –  Jun 16 '17 at 13:08
  • 1
    `create_table` should use `calloc`. You really want each cell to be zeroed (at least to ease debuggging), not left uninitialized. – Basile Starynkevitch Jun 16 '17 at 13:09
  • @BasileStarynkevitch I will change to `calloc()`, thank you. – Ziezi Jun 16 '17 at 13:10
  • [don't cast the result of `malloc` in C](http://stackoverflow.com/q/605845/995714) – phuclv Jun 16 '17 at 13:20
  • 2
    Despite all minor errors, this code as shown here *should not crash*. Which compiler (+version) are you using and on which platform? Which standard C library (+version) is linked? Which flags do you use during compilation? If this **really** is all your code, there's maybe something wrong with the compiler or runtime. –  Jun 16 '17 at 13:24
  • @FelixPalmen MVC++Express2010, Windows 10. Everything (flags) is to its default settings. – Ziezi Jun 16 '17 at 13:29
  • [it works for me](http://coliru.stacked-crooked.com/a/89f60c4ff325167e) – sp2danny Jun 16 '17 at 13:33
  • 2
    @Ziezi Then you are running e.g. an old executable that's not the result of compiling this code. If you create a new solution/project, copy paste the code from here into 2 new files, main.c and table.h, build and run that code, you don't get the crash you have reported. – nos Jun 16 '17 at 13:34
  • 1
    No matter what, start by getting rid of the spaghetti globals. – Lundin Jun 16 '17 at 13:35
  • @nos pff, I'll follow your advice, thank you! – Ziezi Jun 16 '17 at 13:41
  • @Lundin I understand, the thing is that I'm given (interface) function prototypes, that does not have parameters for the `size`, `capacity`, etc...I don't know any other way to do it. – Ziezi Jun 16 '17 at 13:43
  • 1
    @Ziezi The table and its size you allocate and keep track of in main(). The `table_capacity` variable aren't used so it can be removed. And that's it. – Lundin Jun 16 '17 at 13:46
  • @Lundin I see, thank you! – Ziezi Jun 16 '17 at 14:00

0 Answers0