我之前在 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++ 代码隔离。它们是不同的语言。将 C 视为可以在 C++ 中运行,与将繁体中文视为可以在简体中文中运行一样有意义。如果您正在编写一个使用 C++ 编译器进行编译的程序,它可能看起来与您编写的使用 C 编译器进行编译的程序有很大不同。
尽管如此,有时您可能希望将某些 C 代码(或汇编代码或其他代码)链接到 C++ 代码。对于每种语言,该过程可能都是相似的,只要您使用的编译器具有兼容的 ABI。我将使用的示例是
gcc
和 g++
。
使用 C 编译器(例如
gcc
)编译 C 代码,但不进行链接过程(例如使用 -c
标志)。例如:gcc -c split.c
使用 C++ 编译器编译 C++ 代码,并将 C 编译器生成的目标代码链接到其中。例如:
g++ main.cpp split.o