为什么 realloc() 在为 C++ 编译时神秘地表现不同?

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

我以前在 C 程序中多次使用过以下函数:

/**
    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;
}

我最近刚刚将该函数添加到一个 C++ 项目中,以便在我需要处理 C 字符串的情况下使用。编译时,我现在得到这个错误:

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));

我完全不知道如何处理这些错误。就我而言,我正在做的事情在 C++ 中应该是合法的,因为它在 C 中一直运行良好。有什么见解吗?

如果有帮助,我正在 OS X 上使用 clang++ 作为编译器,但此代码也有望在 Ubuntu.

上使用 g++ 编译

C++ 不允许将 void* 指针隐式转换为其他指针。此外,C 和 C++ 是完全不同的语言,因此并非所有 C 都适用于 C++,因为它是一种不同的语言。

不过,显式转换 realloc() 结果应该可行。

在 C 和 C++ 上并非所有内容都必须相同; mallocrealloc 是一个常见的例子。

  1. 您不必在 C 中显式转换 void pointer,它将自动完成,如您的示例所示。
  2. mallocrealloc 函数中,您肯定必须在 C++ 中显式转换该指针。

这两种语言之间有很大的差异,不要想当然。

在此 link 中陈述了 C 和 C++ 之间在基本内容上的一些差异;可能值得一读。

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

或者这个(由评论建议):

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

将 C 代码与 C++ 代码隔离开来。它们是不同的语言。将 C 视为在 C++ 中可以 运行 与将繁体中文视为在简体中文中可以 运行 一样有意义。如果您正在编写一个用 C++ 编译器编译的程序,它可能看起来与您编写的用 C 编译器编译的程序看起来非常不同。

尽管如此,有时您可能希望 link 一些 C 代码(或汇编代码,或其他)到您的 C++ 代码中。每种语言的过程可能都相似,前提是您使用的编译器具有兼容的 ABI。我将使用的示例是 gccg++.

使用您的 C 编译器编译您的 C 代码(例如 gcc),但不使用 linking 过程(例如使用 -c 标志)。例如:gcc -c split.c

使用 C++ 编译器编译 C++ 代码,并将 C 编译器生成的目标代码link 编译到其中。例如:g++ main.cpp split.o