Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.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++_Pointers_Struct - Fatal编程技术网

初始化和维护结构的结构 我编写C++代码来处理从实验室测量中提取的一组直方图。当我试图更好地组织事情时,我遇到了问题,我认为我的问题来自错误地处理指针和/或结构

初始化和维护结构的结构 我编写C++代码来处理从实验室测量中提取的一组直方图。当我试图更好地组织事情时,我遇到了问题,我认为我的问题来自错误地处理指针和/或结构,c++,pointers,struct,C++,Pointers,Struct,我最初的设计是这样的: // the following are member variables Histogram *MassHistograms[3]; Histogram *MomentumHistograms[3]; Histogram *PositionHistograms[3]; 其中,每个阵列的元素0对应于一个实验室测量值,每个阵列的元素1对应于另一个,等等。我可以通过MassHistograms[0]或类似方式访问各个直方图,并且工作正常。然而,在我看来,这个组织并不合适。如

我最初的设计是这样的:

// the following are member variables
Histogram *MassHistograms[3];
Histogram *MomentumHistograms[3];
Histogram *PositionHistograms[3];
其中,每个阵列的元素0对应于一个实验室测量值,每个阵列的元素1对应于另一个,等等。我可以通过
MassHistograms[0]
或类似方式访问各个直方图,并且工作正常。然而,在我看来,这个组织并不合适。如果我要执行一个新的度量,我必须在每个直方图数组中添加一个元素。相反,我想出了

struct Measurement {
    Histogram *MassHistogram;
    Histogram *MomentumHistogram;
    Histogram *PositionHistogram;
};
作为增加复杂性的一层,我还想根据对数据的处理将这些测量捆绑起来,所以我

struct MeasurementSet {
    Measurement SignalMeasurement;
    Measurement BackgroundMeasurement;
};
我认为这种安排更具逻辑性和可扩展性,但它不起作用;-)如果我有这样的代码

MeasurementSet ms;
Measurement m = ms.SignalMeasurement;
Histogram *h = m.MassHistogram;
然后试着用
h
,我发现了一个分段错误。由于类似的代码以前工作得很好,我假设我没有正确处理代码中的结构。具体来说,结构是否需要以任何方式显式初始化?(直方图由其他人的库提供,只需声明直方图*SomeHistograms[4]就足以对其进行初始化。)

我感谢你的反馈。我非常熟悉Python和Culjule,但是我对C++的有限知识并不延伸到[看起来和类似的]结构的照顾和喂养的奥秘:-)/P>
我最终做了什么 我把
Measurement
变成了一门全面的课程:

class Measurement {
    Measurement() {
        MassHistogram = new Histogram();
        MomentumHistogram = new Histogram();
        PositionHistogram = new Histogram();
    };

    ~Measurement() {
        delete MassHistogram;
        delete MomentumHistogram;
        delete PositionHistogram;
    };

    Histogram *MassHistogram;
    Histogram *MomentumHistogram;
    Histogram *PositionHistogram;
}
(我调用的通用的
Histogram()
constructor工作得很好。)我遇到的另一个问题是通过总是通过引用传递
度量值来解决的;否则,将在接收到
测量值的任何函数结束时调用析构函数,并且下一次尝试使用其中一个直方图执行操作时将出错


谢谢大家的回答

当结构包含指针时,必须自己初始化该变量。 例子


您知道您的
测量定义
没有为实际的
直方图
分配内存吗?在您的代码中,
m.MassHistogram
是一个悬空(未初始化)指针,它不指向任何测量的
直方图,也不指向任何能够存储
直方图的内存。正如@Nari Rennlos刚刚发布的,您需要将其指向现有(或新分配的)
直方图

您的第三方库的界面是什么样子的?如果可能的话,您应该有一个
度量
包含3个
直方图
s(而不是指向
直方图
s的3个指针)。这样,当您创建
度量值
度量值集
时,将为您创建相应的
直方图
s,销毁时也是如此。如果仍然需要指针,可以使用
&
运算符:

struct Measurement2 {
    Histogram MassHistogram;
    Histogram MomentumHistogram;
    Histogram PositionHistogram;
};

MeasurementSet2 ms;
Histogram *h = &ms.SignalMeasurement.MassHistogram; //h valid as long as ms lives
还请注意,只要不使用指针(或引用),对象将被复制并按值赋值:

MeasurementSet ms;                    //6 uninitialized pointers to Histograms
Measurement m = ms.SignalMeasurement; //3 more pointers, values taken from first 3 above
Histogram *h = m.MassHistogram;       //one more pointer, same uninitialized value
虽然如果指针已经初始化,那么此时所有10个指针都将指向实际的
直方图

如果有实际的成员而不是指针,情况会变得更糟:

MeasurementSet2 ms;                    //6 Histograms
Measurement2 m = ms.SignalMeasurement; //3 more Histograms, copies of first 3 above
Histogram h = m.MassHistogram;         //one more Histogram

h.firstPoint = 42;
m.MassHistogram.firstPoint = 43;
ms.SignalMeasurement.MassHistogram.firstPoint = 44;

…现在有3个稍有不同的质量信号直方图,2对相同的动量和位置信号直方图,以及三组背景直方图

您确定
直方图*某些直方图[4]
初始化了数据吗?如何填充直方图结构

这里的问题与其说是结构,不如说是让你绊倒的指针。执行此操作时:
MeasurementSet ms它声明MeasurementSet类型的“自动变量”。这意味着MeasurementSet的所有内存都已“分配”并准备就绪。MeasurementSet又有两个类型为Measurement的变量,它们也是“已分配”和“准备就绪”。反过来,度量有3个直方图*类型的变量,它们也是“已分配”和“准备就绪”。。。但是等等!“直方图*”类型是一个“指针”。这意味着它是一个地址——一个描述实际内存位置的32或64位(或任意位)值。就这样。这取决于你如何指向某个东西——在那个位置放置某个东西。在它指向任何东西之前,它实际上会包含随机数据(或者0'd out数据,或者一些特殊的调试数据,或者类似的数据)——关键是如果你试图用它做一些事情,你会得到一个分段错误,因为你可能会试图读取你的程序不应该读取的部分数据

<>在C++中,结构与一个类(在Python中有类似的概念)几乎完全相同,并且通常分配一个类似于:
m.MassHistogram = new Histogram();

…之后,柱状图就可以开始了。然而,YMMV:你能自己分配一个吗?或者你只能从某个库中获得一个,可能是从设备读取,等等?此外,虽然你可以做我写的,但它不一定“漂亮”。c++-ic解决方案是将分配放在构造函数(如python中的init)中,并将删除放在析构函数中。

首先,请始终记住,结构和类几乎完全相同。唯一的区别是结构成员在默认情况下是公共的,而类成员在默认情况下是私有的。 但其余的都是一样的

其次,仔细区分指针和对象

如果我写

Histogram* h;
Histogram* h = new Histogram();
Histogram* copy = h;
Histogram* h = new Historgram;
Histogram* copy = h;
delete h;
直方图h

将为直方图的数据分配空间,并调用其构造函数。(构造是一个与类名称完全相同的方法,这里是Historgr
Histogram* h = new Historgram;
Histogram* copy = h;
delete h;