Exercise 35: Dynamic Array - Undefined behaviour?

After going through Exercise 31: Common Undefined Behavior I couldn’t help but notice a potential undefined behaviour lurking in Exercise 35. I am referring to the way in which the “strings” char *words[] are locally placed on the stack within the function create_words(). After exiting the same function the contents of words are used when testing the sorting algorithms.

If I am not mistaken this is UB of the sorts

An object is referred to outside of its lifetime (6.2.4).

One fix would be to declare words locally within darray_algos_tests.c or place it on the heap instead.

Hi horigome,

I am doing exercise 34 and there is no code for darray_algos_test.c. Are you sure you are referring to exercise 34?

Also, could you show the specific code that is in error? Otherwise I would have to guess what you are referring to and that can not end well.

Kind regards, Guus.

Hi Guus,

yes you are correct, I mixed up exercise 34 (about the dynamic array data structure) and 35 (about algorithms that work on the dynamic array). The piece of code I am referring to is inside the function

DArray *create_words()
    DArray *result = DArray_create(0, 5);
    char *words[] = { "asdfasfd",
        "werwar", "13234", "asdfasfd", "oioj" };
    int i = 0;

    for (i = 0; i < 5; i++) {
        DArray_push(result, words[i]);

    return result;

The words char array is created and placed on the stack. Later, after that same function is exited, the contents of the array is used in the tests.


I am inclined to agree. The confirmation is in the code of DArray_push() where it stores the pointers to the char strings.

int DArray_push(DArray * array, void *el)
    array->contents[array->end] = el;

    if (DArray_end(array) >= DArray_max(array)) {
        return DArray_expand(array);
    } else {
        return 0;

The pointers to el are stored in the stack and will be pointing into memory that is release by the time the caller receives results.

EDIT: Maybe a run into valgrind or electric fence would confirm the problem. When I do ex35 I will see what I can do, but feel free to do it first.

Kind regards, Guus.

P.S. You may want to change the title to reflect the correct exercise (if the forum will allow that).

Ohhhhhh yes, that’s an error. I believe if you change it to:

DArray_push(result, strcpy(words[i]));

Then that’s a quick fix for the test. You’d need to confirm that I’m right here since I’m a little rusty on my C.

I have the printed book - I haven’t done exercise 35 yet - would you consider this a sort of “errata” for it? Speaking of, is there an errata for all printed materials?

I tend to update the source and then work it through my publisher’s errata. If you’re interested in giving me a pull request off github I can point you at the code to do it.

My apologies, please forgive my ignorance, Zed. I don’t understand what you are asking from me when you say “giving me a pull request off github”.

What is it I need to do in order to read all identified errata?

Ah, well github.com is a code hosting place that let’s people like you send me patches and changes. It uses a tool called git which is actually total garbage but, everyone uses it, so, if you’re looking to be a developer it might be a good time to sit down and learn it.

Here’s what you should do:

  1. Go to github.com and create an account.
  2. The project for this is at https://github.com/zedshaw/liblcthw
  3. You can go there and simply submit a bug report with your changes in the report, but if you want to really learn how to do this then you’ll want to do a “pull request”.
  4. A pull request involves you forking the project (there’s a button on github), then you make your changes, commit them, and then back on github you click a button to send me a pull request for your changes.

Here’s their documentation for it https://help.github.com/articles/creating-a-pull-request/ I’d consider this a 2 day project if you want to do it, but once you learn how it’s easy and then you can send anyone patches and contribute to projects.