Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;:读取数据如何可能影响记忆? 最近我一直深入C++,我的bug看起来很复杂。_C++_Mpi_Corruption - Fatal编程技术网

C++;:读取数据如何可能影响记忆? 最近我一直深入C++,我的bug看起来很复杂。

C++;:读取数据如何可能影响记忆? 最近我一直深入C++,我的bug看起来很复杂。,c++,mpi,corruption,C++,Mpi,Corruption,我有一个对象向量,每个对象包含一个浮动向量。我决定需要再创建一个平面数组,其中包含所有对象的所有浮点值。这比这要复杂一点,但问题的要点是,当我在我的对象中循环提取浮点值时,在某个点上,我的对象向量发生了变化,或者以某种奇怪的方式被破坏。(我的读取操作都是常量函数) 另一个例子是MPI。我刚刚开始,所以我只想在两个不同的节点上运行完全相同的代码,使用它们自己的内存,并且不发生数据传输,所有这些都非常简单。令我惊讶的是,我得到了分段错误,经过数小时的跟踪,我发现一个变量的赋值将一个完全不同的变量设置

我有一个对象向量,每个对象包含一个浮动向量。我决定需要再创建一个平面数组,其中包含所有对象的所有浮点值。这比这要复杂一点,但问题的要点是,当我在我的对象中循环提取浮点值时,在某个点上,我的对象向量发生了变化,或者以某种奇怪的方式被破坏。(我的读取操作都是常量函数)

另一个例子是MPI。我刚刚开始,所以我只想在两个不同的节点上运行完全相同的代码,使用它们自己的内存,并且不发生数据传输,所有这些都非常简单。令我惊讶的是,我得到了分段错误,经过数小时的跟踪,我发现一个变量的赋值将一个完全不同的变量设置为NULL

所以我很好奇,读操作怎么可能影响我的数据结构。类似地,一个看似无关的操作如何影响另一个操作。我不能指望用这些简短的描述来解决我的问题,但任何建议都将不胜感激

更新: 这是代码的一部分,我最初没有发布,因为我不确定在不了解整个系统的情况下可以从中提取多少

但我刚刚发现的一件事是,当我停止将值分配给平面数组而改为不分配时,seg错误消失了。因此,也许我声明我的数组是错误的,但即使我是,我也不确定它会如何影响对象向量

void xlMasterSlaveGpuEA::FillFlatGenes() {
    int stringLength = pop->GetGenome(0).GetLength();
    for (int i=0;i<pop->GetPopSize();i++)
        for (int j=0;j<stringLength;j++)
            flatGenes[(i*stringLength)+j]<< pop->GetGenome(i).GetFloatGene(j);
}

float xlVectorGenome::GetFloatGene(unsigned int i) const {
    return GetGene(i);
}
在构造函数中初始化,如下所示:

flatFitness = new float(popSize);
更新2:

我只想指出,上面的两个例子并不相关,第一个不是多线程的。第二个MPI示例在技术上是,但MPI是分布式内存,我特意尝试了我所能想到的最简单的实现,即两台机器都独立运行代码。不过,还有一个额外的细节,我附加了一句话

if node 1 then do bottom half of loop

if node 1 then do top half

同样,记忆应该被隔离,他们应该像互不了解一样工作。。但是删除这个条件并使两个循环都执行所有多维数据集,就消除了错误

我怀疑您有多线程或内存损坏问题,您可能没有意识到。您所描述的行为并不是任何一种标准的、设计上令人满意的行为。

jeffamaphone可能是对的,这是一个线程问题。另一种可能是您正在阅读的对象已被删除。然后,您将从无效地址读取。您此时写入的数据结构也可能存储在向量以前占用的同一位置。这将导致您描述的行为

编辑(根据您的更新):

这可能是错误的:
stringLength
在外循环外部初始化,但看起来需要在外循环期间进行更新:

int stringLength = pop->GetGenome(0).GetLength();
for (int i=0;i<pop->GetPopSize();i++)
    for (int j=0;j<stringLength;j++)
        flatGenes[(i*stringLength)+j]<< pop->GetGenome(i).GetFloatGene(j);
intstringlength=pop->GetGenome(0.GetLength();
对于(int i=0;IGETOPSIZE();i++)
对于(int j=0;jGetGenome(i).GetLength();

对于(int j=0;j这不是数组构造函数:

float * flatFitness;
flatFitness = new float(popSize);
您正在这里的堆上创建一个浮点数,用value
popSize
初始化。如果您想要浮点数数组,您需要使用括号而不是括号:

float *flatFitness = new float[popSize];
这很容易导致您描述的问题。此外,请记住,在创建阵列时,您需要使用
delete[]
(最终):

如果只使用
delete
,它可能会工作,但行为尚未定义

如果您想避免完全使用数组语法,为什么不使用
std::vector
?您可以创建popSize元素的向量,如下所示:

#include <vector>

std::vector<float> flatFitness(popSize);
#包括
std::向量平坦适合度(popSize);
当它超出范围时将自动释放,因此您不必担心
new
delete


更新(re:comment):如果您已经在代码的其他地方使用了
std::vector
,请查看
std::vector::swap()
。您可以完全避免复制内容,只需在CUDA缓冲和您正在执行的处理之间来回交换两个向量。

您可以发布代码的浓缩版本吗?很难从这一点判断可能发生的情况。您可以将循环代码发布到迭代CUDA中的对象的位置吗vector…可能您正在内存上?读取操作不会更改值。代码中一定有其他内容。第二个示例是一个变量指向错误位置的典型情况。是的,这听起来像是一个缺少内存屏障和线程间同步不足的教科书案例。它只会使一个线程在另一个线程看到数据对象后的某个时间点更新该数据对象,而缺少同步迟早会影响到你。也许,除非他从未说过他在使用线程。MPI是进程级并行,除非你将其与其他东西结合起来。够有趣的是,我正在从std::vectors中提取数据,因为我需要通过CUDA将其发送到GPU。可能有一种更优雅的方法来查看vector::swap()。您可以在此处实例化一些向量,然后将它们与CUDA使用的向量交换,这样您就不必进行任何复制。只需使用resize()或构造函数(如上所述)确保它们的大小正确即可,否则,您可能最终会写入您没有的内存。
float *flatFitness = new float[popSize];
delete [] flatFitness;
#include <vector>

std::vector<float> flatFitness(popSize);