使用C从C ++访问公共类内存

问候每个人。

我目前正在UNIX上编写C,C ++和fortran的多语言程序,不幸的是,当我在编译后尝试执行时遇到“分段错误”。

我已经将问题缩小到我程序的C ++和C部分之间的接口。 第一部分包括main.ccp和SA.cpp,以及第二部分CFE.c.

一个名为’SimAnneal’的类在SA.cpp中存在,具有公共向量DensityArray和ElementArray。 该计划的顺序如下:

  1. 创建SimAnneal对象’Obj1’并调用函数ObjFunction()

  2. 该函数初始化矢量大小

  3. 使用指向两个向量及其长度的指针调用CFE(…)。

  4. CFE.c通过使用指针直接编辑向量的数据元素

  5. ObjFunction()使用EnergyArray(和可能的DensityArray)数据。

所有来源的相关脚本如下:

main.cpp中

#include "SA.h" int main() { SimAnneal Obj1; Obj1.ObjFunction(); return 0; } 

SA.h

 class SimAnneal { void Initialize (); ... public std::vector DensityArray; std::vector EnergyArray; double ObjFunction (); ... } 

SA.cpp

 #include "CFE.h" void SimAnneal::Initialize () { int length = 15; EnergyArray.resize(length); DensityArray.resize(length); } double SimAnneal::ObjFunction () { Initialize (); CFE(&DensityArray[0], &EnergyArray[0], DensityArray.size()); // sends pointers of both arrays to CFE.c, which will then // directly modify the array double SumStrainEnergy = 0; for (int i = 0; i < EnergyArray.size(); i++) { SumStrainEnergy += EnergyArray[i]; //Effectively sum of array //engy[] from CFE.c } return SumStrainEnergy; } 

CFE.h

 #ifdef __cplusplus extern "C" { #endif void CFE(float density[], float energy[], int NumElem); #ifdef __cplusplus } #endif 

CFE.c

 void CFE(float density[], float energy[], int NumElem) { ... float * dens; dens = density; //pass pointer of array density[0] in SA.cpp to CFE.c for(n=0; n<NumElem; n++) { ... modify dens (eg DensityArray from SA.cpp) ... } float * engy; engy = energy; //pass pointer of array energy[0] in SA.cpp to CFE.c for(n=0; n<NumElem; n++) { ... modify engy (eg EnergyArray from SA.cpp) ... } } 

我是否通过尝试从程序的C部分访问向量元素来导致非法的内存访问? 有没有确定的方法允许这个?

任何帮助都会很有帮助。

如果你保持在向量的范围内,你正在做的事情似乎没问题。

通过执行您正在执行的操作,您可以将std :: vector完全视为C数组 – 获取第一个元素的地址。 C ++标准已经更改为专门允许这种用法。

目前无法找到C ++的技术勘误表副本2003,但显然相关部分参考文献是23.2.4,

您发布的代码似乎没问题 – 如果您希望调试问题,则需要提供更多详细信息。 实际上,如果你在调试器中运行程序,它应该能够准确地告诉你导致exception的代码行(你可能必须查看调用堆栈),或者只是单步执行程序直到它崩溃。

至于关于vector是否可以被视为C数组的混淆,它肯定可以通过获取第一个元素的地址(即。, &vect[0] ) – 如果向量包含元素。

C ++ 03标准在23.2.4中说明了vector<>

向量的元素是连续存储的,这意味着如果vvector ,其中T是除bool之外的某种类型,则它遵循所有0 <= n < v.size()的标识&v[n] == &v[0] + n 0 <= n < v.size()

请注意,这在C ++ 98标准中没有明确说明(但仍然是意图)。

另见Herb Sutter的文章:

请注意, vector不能被视为C数组 - 这是一种特殊情况,因为vector中的元素不会存储为bool

你不能这样做。 Vector类与C类数组不同。

在将其传递给CFE函数之前,必须将其转换为常规C数组。

编辑:显然我的回答是错误的。 查看Neil的post。

您发布的代码是正确的。 如果对CFE()内部的数组元素的每次访问都在边界内,则不应该出现分段错误。 尝试在valgrind下运行您的程序,看看它是否报告任何exception。

CFE()的内容是什么?

为什么不将CFE()定义为; void CFE(float * density,float * energy,int NumElem);

所以你不必愚弄演员,只是这样做; 密度[i] = …在你的循环内?