Copying a vector between trees in a loop

Hi

I am using ROOT 5.34/36 on Arch Linux. I am trying to make a script that copies a vector from one tree to another. The code keeps segfaulting. Here is a skeleton of what I am trying to do. Any suggestions for fixing this would be appreciated. Thanks in advance!

#include <iostream>
#include <vector>
#include <TFile.h>
#include <TTree.h>

using namespace std;

TTree* InputTree(TFile* fin, const char* TreeName, vector<int>* vec){

  TTree *tree = (TTree*)fin->Get(TreeName); //Declare tree to be returned

  TBranch *BVEC = 0;
  tree->SetBranchAddress("waveform", &vec, &BVEC); //Copy original waveform vector into a vector passed to the function

  return tree;
} 

void Test(){

	int i = 0;

	vector<int> Vec1;
	vector<int>* Vec1_ptr = &Vec1;

	TFile* fin = TFile::Open("data.root"); //Open data file
	TTree* DataTree = InputTree(fin, "DataTreeOld", Vec1_ptr); //Copy array "waveform" from the original DataTree tree into a new DataTree tree
	
	DataTree->GetEntry(i);
	cout << Vec1.size() << endl;
	
	while(i < DataTree->GetEntries()){
	
		i++;
		DataTree->GetEntry(i);
		cout << Vec1.size() << endl;
	}
}

With the code:

TTree* InputTree(TFile* fin, const char* TreeName, vector<int>* vec){
  ....
  TBranch *BVEC = 0;
  tree->SetBranchAddress("waveform", &vec, &BVEC);

the TTree object retain the address of two temporary variable and will attempt to write at their location even after their memory location has been reused.
do:

void Test(){

  int i = 0;

  vector<int> Vec1;
  vector<int>* Vec1_ptr = &Vec1;

  TFile* fin = TFile::Open("data.root"); //Open data file

  TBranch *BVEC = 0;

  TTree *tree  = nullptr;
   fin->Get(TreeName, tree);

   if (!tree) return;

   tree->SetBranchAddress("waveform", &Vec1_ptr, &BVEC); 
	
  DataTree->GetEntry(i);
  cout << Vec1.size() << endl;
	
  while(i < DataTree->GetEntries()){
	
    i++;
    DataTree->GetEntry(i);
    cout << Vec1.size() << endl;
  }
}

Also note

tree->SetBranchAddress("waveform", &vec, &BVEC); //Copy original waveform vector into a vector passed to the function

The comment is inaccurate. SetBranchAddress just tell the TTree where it will be looking for the address of the object where to put the data when GetEntry is called. I.e. internally it does something akin to:

   vector<int>** fPtrToObjectPtr = &vec;
   TBranch ** fPtrToBranchPtr = &BVEC;
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.