Search code examples
c++crealloc

Why is realloc() mysteriously behaving differently when compiled for C++?


I have the following function that I've used in C programs plenty of times before:

/**
    Splits a given string into an array of strings using given delimiters.
    @param input_string
        The string to be split.
    @param delimiters
        The characters that will be used as delimiters.
    @return
        The components of the split string followed by @c NULL , or only
        @c NULL if sufficient memory fails to allocate for the returned array.
 */
char **split(char *input_string, const char *delimiters) {
    char **components = NULL;
    int components_count = 0;

    char *component = strtok(input_string, delimiters);
    while (component) {
        ++components_count;

        // |components| is reallocated to accomodate |component|. If
        // |realloc()| fails, |NULL| is returned.
        components = realloc(components, sizeof(char *) * components_count);
        if (!components) return NULL;
        components[components_count - 1] = component;

        component = strtok(NULL, delimiters);
    }

    // |components| is reallocated once more to accomodate an additional
    // |NULL|. Only |NULL| is returned in |realloc()| fails.
    components = realloc(components, sizeof(char *) * (components_count + 1));
    if (!components) {
        return NULL;
    }
    components[components_count] = NULL;

    return components;
}

I just recently added the function to a C++ project to use in a situation where I was required to deal with C-strings. When compiling, I now get this errors:

error: assigning to 'char **' from incompatible type 'void *'
        components = realloc(components, sizeof(char *) * components_count);

error: assigning to 'char **' from incompatible type 'void *'
    components = realloc(components, sizeof(char *) * (components_count + 1));

I'm completely lost as to what to do about these errors. As far as I'm concerned, what I'm doing should be legal in C++ since it's always worked fine in C. Any insight?

If it helps, I'm am using clang++ on OS X as a compiler, but this code is also expected to compile with g++ on Ubuntu.


Solution

  • Not everything has to be the same on C and C++; malloc and realloc is a usual example of this.

    1. You don't have to explicitly cast the void pointer in C, it will be done automatically, as in your example.
    2. You definitely have to explicitly cast that pointer in C++, both in malloc and realloc functions.

    There is a great deal of differences between those two languages, don't take everything for granted.

    In this link some differences on basic stuff between C and C++ are stated here; it might be worth reading it.

    http://www.cprogramming.com/tutorial/c-vs-c++.html

    Or this (suggested by a comment):

    http://david.tribble.com/text/cdiffs.htm