簡體   English   中英

在C ++中將數組傳遞給函數會更改其值,而無需在函數內部執行任何更改

[英]Passing array to function in C++ changes it's value without me performing any change inside the function

我在使用C ++數組時遇到一個非常奇怪的問題。 一切正常,直到將其傳遞給函數以將其寫入磁盤,之后,無需我執行任何操作即可更改陣列。

    int saveMatrix(Long64_t*, unsigned int, const char*);

    void resetArray(Long64_t* array, unsigned int size)
    {
        for (unsigned long int i = 0; i < size; i++)
            array[i] = 0;
    }

    int saveMatrix(Long64_t* array, unsigned int size, const char* filename)
    {
        // Returns:
        //  0 - Exit
        //  1 - Error

        ofstream out(filename, ios::out);
        if (!out) {
            cout << "Cannot open file.";
            return 1;
        }

        for (unsigned long int i = 0; i < size; i++) {
            out << array[i] << " ";
        }

        out.close();

        return 0;
    }

int main(int argc, char** argv) {
    if (argc != 2) {
        cout << "The program needs the name of the ROOT file to analyse." << endl;
        return 1;
    }
    else
        return gf_partial(argv[1]);
}
#endif

#include "../include/ROOT_Tree.hh"
#include "jbmArray.hh"

int gf_partial(const char* name) {
    // init macro
    gROOT->Reset();

    unsigned long int i, j;

    const unsigned int DetectorNumber = 4;
    /* Detectors are:
     0 lefs60Foil
     1 lefs60Fl
     2 lefs60Ml
     3 lefs150Foil
     4 lefs150F
     5 lefs150M
     6 ca60D
     7 ca60C
     8 ca60B
    */
    const double sourceRadius = 20.; // LAN2B In cm
    // const double sourceRadius = 11.; // LAN2A In cm
    const Int_t numberOfChannels = 4;
    // Float_t energyChannels[numberOfChannels] = {52., 85., 141., 227.}; // LAN2A F electron
    Float_t energyChannels[numberOfChannels] = {51., 80., 135., 218.}; // LAN2B F electron
    // Float_t energyChannels[numberOfChannels] = {42., 55., 130., 220.}; // LAN2B B electron
    // Float_t energyChannels[numberOfChannels] = {66., 101., 167., 269., 447., 798., 1391., 2926.}; // LAN2B M proton
    const Int_t numberOfDetectors = 9;
    Float_t energyChannelsError[numberOfChannels] = {0., 0., 0., 0.};
    // Float_t energyChannelsError[numberOfChannels] = {0., 0., 0., 0., 0., 0., 0., 0.};

    Float_t vGeometryFactors[numberOfChannels];
    Float_t vError[numberOfChannels]; // the error amount
    Float_t vRealError[numberOfChannels]; // the calculated error

    Long64_t nHitsInDetector[numberOfChannels];
    resetArray(nHitsInDetector, numberOfChannels);

    Long64_t nHitsInDetectorNoSecondaries[numberOfChannels];
    resetArray(nHitsInDetectorNoSecondaries, numberOfChannels);

    double nEmitedParticlesPerChannel[numberOfChannels];
    resetArray(nEmitedParticlesPerChannel, numberOfChannels);

    //exclusiongraph()->Update();

    if (!TClassTable::GetDict("Event")) {
        gSystem->Load("../lib/libROOT_Tree.so");
    }

    // read the tree file generated in GEANT4
    TFile* treeFile = new TFile(name);
    treeFile->ls();
    TTree *myTree = (TTree*) treeFile->Get("hiscaleSim");

    // Create pointer to an event object for reading the branch values.
    Event* myEvent = new Event();
    TBranch* bEvent = myTree->GetBranch("EventBranch");
    bEvent->SetAddress(&myEvent);

    TClonesArray* hits = myEvent->GetHits();
    Hit* myHit;

    unsigned long int nEvents = myTree->GetEntries();
    cout << endl << "Number of Total Events = " << nEvents << endl << endl;

    Float_t sourceEnergy = 0.0;
    Float_t depositedEnergy = 0.0;
    Float_t sourceTime = 0.0;
    UInt_t parentID = 0;
    UInt_t trackID = 0;

    std::vector<float> fSourcePosition(3);
    std::vector<float> minSourcePosition(3);
    std::vector<float> maxSourcePosition(3);

    std::vector<float> fSourceMomentumDirection(3);
    std::vector<float> minSourceMomentumDirection(3);
    std::vector<float> maxSourceMomentumDirection(3);

    std::vector<float> totalDepositedEnergy(numberOfDetectors);
    //std::vector<unsigned long int> nHitsInDetector(numberOfDetectors);

    // std::vector<unsigned long int> nHitsInDetectorNoSecondaries(numberOfChannels);

    Float_t fParticlePDGMass = 0.0;
    Float_t fParticlePDGCharge = 0.0;
    //fParticleAtomicNumber = 0;
    //fParticleAtomicMass = 0;

    for (i = 0; i < nEvents; i++) {
        myTree->GetEntry(i);

        depositedEnergy = 0;
        sourceEnergy = myEvent->GetSourceEnergy();
        for (j = 0; j < myEvent->GetNHit(); j++) {
            myHit = (Hit*)hits->UncheckedAt(j);
            if (myHit->GetDetectorN() == DetectorNumber)
                depositedEnergy = myHit->GetTotalDepositedEnergy();
        }

        parentID = myEvent->GetParentID();
        trackID = myEvent->GetTrackID();

        for (j = 0; j < numberOfChannels; j++) {
            if (sourceEnergy == energyChannels[j]) {
                nEmitedParticlesPerChannel[j]++;
                if (depositedEnergy != 0) {
                    if (parentID == 0)
                        nHitsInDetectorNoSecondaries[j]++;
                    nHitsInDetector[j]++;
                }
            }
        }
    }

    char strnHitsInDetector[80];
    strcpy (strnHitsInDetector, name);
    strcat (strnHitsInDetector, ".nHitsInDetector");
    saveMatrix(nHitsInDetector, numberOfChannels, strnHitsInDetector);

    //char strnHitsInDetector[80];
    strcpy (strnHitsInDetector, name);
    strcat (strnHitsInDetector, ".nHitsInDetectorNoSecondaries");
    saveMatrix(nHitsInDetectorNoSecondaries, numberOfChannels, strnHitsInDetector);

    char strnEmitedParticlesPerChannel[80];
    strcpy (strnEmitedParticlesPerChannel, name);
    strcat (strnEmitedParticlesPerChannel, ".nEmitedParticlesPerChannel");
    saveMatrix(nEmitedParticlesPerChannel, numberOfChannels, strnEmitedParticlesPerChannel);

// from now on nEmitedParticlesPerChannel changes it's value and it's not ok anymore.

我認為問題出在以下幾行代碼中:

const Int_t numberOfChannels = 2;

Long64_t nEmitedParticlesPerChannel[numberOfChannels];
resetArray(nEmitedParticlesPerChannel, numberOfChannels);

nEmitedParticlesPerChannel[1] = 10;
nEmitedParticlesPerChannel[2] = 20;

請注意,已將數組nEmittedParticlesPerChannel大小nEmittedParticlesPerChannel為在其中包含兩個元素,然后寫入索引1和2。由於C ++數組的索引為零,這意味着您要注銷數組的末尾並破壞其中的任何值。記憶恰好在它之后。 這可能會破壞您作為參數傳入的數組的內容,因為這會導致未定義的行為。

要解決此問題,請嘗試將最后兩行重寫為

nEmitedParticlesPerChannel[0] = 10;
nEmitedParticlesPerChannel[1] = 20;

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM