为什么 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++ 上并非所有内容都必须相同; malloc
和 realloc
是一个常见的例子。
- 您不必在 C 中显式转换
void pointer
,它将自动完成,如您的示例所示。
- 在
malloc
和 realloc
函数中,您肯定必须在 C++ 中显式转换该指针。
这两种语言之间有很大的差异,不要想当然。
在此 link 中陈述了 C 和 C++ 之间在基本内容上的一些差异;可能值得一读。
http://www.cprogramming.com/tutorial/c-vs-c++.html
或者这个(由评论建议):
将 C 代码与 C++ 代码隔离开来。它们是不同的语言。将 C 视为在 C++ 中可以 运行 与将繁体中文视为在简体中文中可以 运行 一样有意义。如果您正在编写一个用 C++ 编译器编译的程序,它可能看起来与您编写的用 C 编译器编译的程序看起来非常不同。
尽管如此,有时您可能希望 link 一些 C 代码(或汇编代码,或其他)到您的 C++ 代码中。每种语言的过程可能都相似,前提是您使用的编译器具有兼容的 ABI。我将使用的示例是 gcc
和 g++
.
使用您的 C 编译器编译您的 C 代码(例如 gcc
),但不使用 linking 过程(例如使用 -c
标志)。例如:gcc -c split.c
使用 C++ 编译器编译 C++ 代码,并将 C 编译器生成的目标代码link 编译到其中。例如:g++ main.cpp split.o
我以前在 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++ 上并非所有内容都必须相同; malloc
和 realloc
是一个常见的例子。
- 您不必在 C 中显式转换
void pointer
,它将自动完成,如您的示例所示。 - 在
malloc
和realloc
函数中,您肯定必须在 C++ 中显式转换该指针。
这两种语言之间有很大的差异,不要想当然。
在此 link 中陈述了 C 和 C++ 之间在基本内容上的一些差异;可能值得一读。
http://www.cprogramming.com/tutorial/c-vs-c++.html
或者这个(由评论建议):
将 C 代码与 C++ 代码隔离开来。它们是不同的语言。将 C 视为在 C++ 中可以 运行 与将繁体中文视为在简体中文中可以 运行 一样有意义。如果您正在编写一个用 C++ 编译器编译的程序,它可能看起来与您编写的用 C 编译器编译的程序看起来非常不同。
尽管如此,有时您可能希望 link 一些 C 代码(或汇编代码,或其他)到您的 C++ 代码中。每种语言的过程可能都相似,前提是您使用的编译器具有兼容的 ABI。我将使用的示例是 gcc
和 g++
.
使用您的 C 编译器编译您的 C 代码(例如 gcc
),但不使用 linking 过程(例如使用 -c
标志)。例如:gcc -c split.c
使用 C++ 编译器编译 C++ 代码,并将 C 编译器生成的目标代码link 编译到其中。例如:g++ main.cpp split.o