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

时间:2015-04-05 00:00:12

标签: c++ c realloc

我有以下功能,我以前在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 ++编译。

3 个答案:

答案 0 :(得分:4)

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

  1. 您不必在C中明确地投射void pointer,它将自动完成,如您的示例所示。
  2. 您必须在mallocrealloc函数中明确地在C ++中强制转换该指针。
  3. 这两种语言之间存在很大差异,不要把一切视为理所当然。

    在这个链接中,这里说明了C和C ++之间基本内容的一些差异;可能值得一读。

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

    或者这(评论建议):

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

答案 1 :(得分:3)

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

显式地转换realloc()结果应该可以正常工作。

答案 2 :(得分:1)

将C代码与C ++代码隔离开来。他们是不同的语言。像处理C ++一样处理C就像处理繁体中文一样有意义,就好像它可以用简体中文运行一样。如果您正在编写一个用C ++编译器编译的程序,那么它应该与您编写的用C编译器编译的程序看起来非常不同。

尽管如此,有时您可能希望将某些C代码(或汇编代码或其他代码)链接到C ++代码。对于每种语言,该过程可能类似,只要您使用的编译器具有兼容的ABI。我将使用的示例是gccg++

使用C编译器编译C代码(例如gcc),但没有链接过程(例如使用-c标志)。例如:gcc -c split.c

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