向所有人致意。
我目前正在UNIX上编写C,C ++和fortran的多语言程序,不幸的是,当我在编译后尝试执行时遇到“分段错误”。
我已经将问题缩小到我程序的C ++和C部分之间的接口。第一部分包括main.ccp和SA.cpp,以及第二部分CFE.c.
一个名为'SimAnneal'的类在SA.cpp中存在,具有公共向量DensityArray和ElementArray。该计划的顺序如下:
创建SimAnneal对象'Obj1'并调用函数ObjFunction()
该函数初始化矢量大小
使用指向两个向量及其长度的指针调用CFE(...)。
CFE.c通过使用指针直接编辑向量的数据元素
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<float> DensityArray;
std::vector<float> 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 (e.g. 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 (e.g. EnergyArray from SA.cpp) ... }
}
我是否通过尝试从程序的C部分访问向量元素来导致非法内存访问?有没有可靠的方法允许这个?
任何帮助都会受到很大关注。
答案 0 :(得分:11)
如果你保持在向量的范围内,你正在做的事情似乎没问题。
你可以通过做你正在做的事情来处理std :: vector,就像它是一个C数组一样 - 取第一个元素的地址。 C ++标准已经更改为专门允许这种用法。
目前无法找到C ++的技术勘误表2003,但显然相关部分参考文献是23.2.4,
答案 1 :(得分:1)
您发布的代码似乎没问题 - 如果您希望调试问题,则需要提供更多详细信息。实际上,如果你在调试器中运行程序,它应该能够准确地告诉你导致异常的代码行(你可能需要查看调用堆栈),或者只是单步调试程序直到它崩溃。 / p>
至于关于vector是否可以被视为C数组的混淆,它肯定可以通过获取第一个元素的地址(即。&vect[0]
) - 如果向量包含元素。
C ++ 03标准在23.2.4中说明vector<>
:
向量的元素是连续存储的,这意味着如果
{1}}v
是vector<T, Allocator>
,其中T
是除bool
以外的某种类型,那么它就服从&v[n] == &v[0] + n
所有0 <= n < v.size()
请注意,这在C ++ 98标准中没有明确说明(但仍然是意图)。
另见Herb Sutter的文章:
请注意,vector<bool>
不能被视为C数组 - 这是一种特殊情况,因为vector<bool>
中的元素未存储为bool
。
答案 2 :(得分:0)
你做不到。 Vector类与C类数组不同。
在将其传递给CFE函数之前,必须将其转换为常规C数组。
编辑: 显然我的回答是错误的。查看Neil的帖子。
答案 3 :(得分:0)
您发布的代码是正确的。如果对CFE()
内部的数组元素的每次访问都在边界内,则不应该出现分段错误。尝试在valgrind下运行您的程序,看看它是否报告任何异常。
答案 4 :(得分:0)
CFE()的内容是什么?
为什么不将CFE()定义为; void CFE(float * density,float * energy,int NumElem);
所以你不必愚弄演员而只是这样做;密度[i] = ...在你的循环里面?