0

I'm writing a cross platform app in C. On Linux and macOS it works fine - no leaks, no crashes, large datasets can be loaded and edited without problem.

On Windows (with GTK 3, MinGW and using CLion) it can be relied upon to crash - I can't predict how many hundred bytes of dataset it will load before crashing, but sooner rather than later it will crash. The crash always occurs when freeing memory. If I remove the free then the code runs in debug mode (but not in non-debug mode). If I'm editing the file then the crash happens - anywhere that memory gets freed the code might crash.

One example of code which crashes is this:

void tree_cell_edited (GtkCellRendererText *cell, const gchar *path_string, const gchar *new_text, gpointer data) {
    GtkTreeModel *model = (GtkTreeModel *)data;

    GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
    GtkTreeIter iter;
    gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column_number"));
    gtk_tree_model_get_iter (model, &iter, path);

    char *upd_text=(char *)calloc( strlen(new_text) * 2, sizeof(char) );
    strcpy(upd_text, new_text);

    gtk_tree_store_set(GTK_TREE_STORE (model), &iter, column, upd_text, -1);

    free(upd_text);
    gtk_tree_path_free (path);
}

If I comment out free(upd_text); then it won't crash - but it only won't crash in Debug mode, and this isn't the right solution to the problem.

Is there something wrong with this code? Why would freeing memory cause the crash - it hasn't been freed anywhere else (unless Windows has some garbage collection mojo going on even for C.)

SOLVED For some reason, the issue was down to insufficient memory being allocated. Curious that it didn't cause a problem on MacOS or Linux.

headbanger
  • 1,038
  • 1
  • 11
  • 32
  • Use [valgrind](http://valgrind.org) and [address sanitizer](https://en.wikipedia.org/wiki/AddressSanitizer) on Linux (e.g. `gcc -fsantize=address` [on](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) Linux with GCC) – Basile Starynkevitch Dec 12 '19 at 10:01
  • What is `validator_ptr` and what does it do with `&upd_text`? – Some programmer dude Dec 12 '19 at 10:02
  • 2
    It's probably undefined behaviour caused by some bug somewhere in your code. And on Linux and macOS you're getting away with it. – Jabberwocky Dec 12 '19 at 10:02
  • 2
    In `calloc( strlen(new_text) * 2, sizeof(char) );` should that be `(strlen(new_text) + 1) * 2` ? It's a frequent mistake not to allow room for a nul terminator. I know you multiply by 2 but is that for other reasons? – Weather Vane Dec 12 '19 at 10:07
  • Some programmer dude - validator_ptr is a red herring. The problem happens wherever there is a free. In answer to your question though, it's a function pointer to the validator code for the edit. – headbanger Dec 12 '19 at 10:08
  • What is the type of the value you set with `gtk_tree_store_set` ? Is it `G_TYPE_STRING`? – Gerhardh Dec 12 '19 at 10:09
  • 4
    No the problem *isn't* with `free`, that's the red herring. You do something with the pointer `upd_text` that causes `free` to crash. But what do you do with the pointer? And where do you do it? Perhaps your validator function make it point somewhere else, to some memory that wasn't allocated with `malloc` (et. al.)? – Some programmer dude Dec 12 '19 at 10:10
  • Does it crash in the call to `free`or somewhere else? – Gerhardh Dec 12 '19 at 10:12
  • 1
    Whenever a program crashes upon `free()`, it means that the heap has been corrupted by _bugs elsewhere in the program_, such as pointer corruptions, array out of bounds access etc. Not necessarily related to the variable passed to `free()`. _This_ is why we must always call `free()`, to expose latent bugs as early as possible, before they come back to bite us far later during full production. – Lundin Dec 12 '19 at 10:12
  • 2
    And now when you removed that call to the validator function, does it *still* crash when you call `free`? – Some programmer dude Dec 12 '19 at 10:12
  • 1
    By the way, in C you [don't have to (and really shouldn't IMO) cast the result of `malloc` or `calloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). In fact such a cast *could* lead to undefined behavior and possible crashes. – Some programmer dude Dec 12 '19 at 10:13
  • By the way, `strlen(new_text) + 1` is enough memory to allocate to be able to fit the null-terminator. And you can use `malloc` instead of `calloc` to save the zeroing of the memory. And perhaps you don't need to allocate memory at all, if all you will do is read the contents of `new_text`? – Some programmer dude Dec 12 '19 at 10:47
  • @Someprogrammerdude It's all solved now. It was down to insufficient memory being alloc'd. I wonder why it didn't cause a problem on Linux or MacOS - not even as far as Valgrind was concerned? But when I allocate more memory on Windows the problem seems to go away. Curious. But thanks for all your help. – headbanger Dec 12 '19 at 13:27

0 Answers0