0

so I'm having an issue passing an entire array of histograms into a function in C++

the arrays are declared like this

TH1F *h_Energy[2];
h_Energy[0] = new TH1F("h1", "h1", 100, 0, 100);
h_Energy[1] = new TH1F("h2", "h2", 100, 0, 100);

And here is what I'm trying to do in the function:

void overlayhists(TH1 *hists, int numhists) {
    int ymax = 0;
    for (int i=0; i<numhists; i++) {
        if (hist[i].GetMaximum() > ymax) {
            ymax = (hist[i].GetMaximum())*1.05;
        }
     }
}

And I'm passing the function an array like this

overlayhists(*h_Energy, 2);

Where h_Energy is an 1D array with 2 elements. The code will run through the first histogram in the loop but as soon as it starts the second loop and tries to access hist[i].GetMaximum() on the second try it segfaults.

What gives?

7
  • show us the code that call overlayhists Commented Apr 23, 2015 at 16:36
  • What is TH1F? Can you please show how it is defined? Commented Apr 23, 2015 at 16:38
  • I edited my comment to show how I call overlayhists and ryyker TH1F is a ROOT 1 dimensional float histogram class. Commented Apr 23, 2015 at 16:39
  • By TH1F *h_histogram[2]; did you actually mean an array of pointers? Commented Apr 23, 2015 at 16:42
  • cmon - please show us the relevant code, why show us the declaration of h_histogram and then show a call using h_Energy Commented Apr 23, 2015 at 16:43

4 Answers 4

2

This creates an array of pointers to type TH1F

TH1F *h_Energy[2]; //edited after OP changed 

If you want to use this, and subsequently pass it as an argument You must first initialize it, and then create your function prototype to accommodate:

void overlayhists(TH1F **hists, int numhists);  
                      ^^

From what you have shown above, you would call it like this: (after your initializations)

h_Energy[0] = new TH1F("h1", "h1", 100, 0, 100);
h_Energy[1] = new TH1F("h2", "h2", 100, 0, 100);

overlayhists(h_Energy, 2);
Sign up to request clarification or add additional context in comments.

3 Comments

How should I call the function then if I want to pass it an array? overlayhists(**h_Energy, 2); or overlayhists(h_Energy,2);
Call it as f(h_Energy), not f(**h_Energy), and access hists[i]->getMaximum() in the function, not hists[i].getMaximum()
overlayhists(h_histogram, 2); //or some other value with actual number of hists if ever other than two. I used two here because that is the current order of your array,
1

1. Passing any array to function in c++ to change the content:

Refer to this code snippet:

//calling:

int nArr[5] = {1,2,3,4,5};

Mul(nArr, 5);

Whenever you pass an array to function you actually pass the pointer to first element of the array. This is implicit to C++ and C. If you pass normal value(non array) it will be considered as pass by value though.


// Function Mul() declaration and definition

void MUl(int* nArr, size_t nArrSize){

 size_t itr = 0;

 for(;itr<nArrSize; itr++)
      nArr[i] = 5*nArr;// here we've coded to multiply each element with 5
}

2. Passing any Ptr to function in c++ to change what pointer is pointing to:

Now let us suppose we want to copy nArr (from above code snippet) to another array, say nArrB

The best way for a beginner would be to use reference to the pointer. You can pass reference to the pointer to your function //so we had

int nArr[5] = {1,2,3,4,5}; int *nArrB;

Here we don't know the gonnabe size of nArrB. to copy nArr to nArrB we have to pass nArr, address of pointer to nArrB(or reference to pointer of nArrB or pointer to pointer of nArrB) and size of array. Here is the implementation.

//Calling

CopyNArr(nArr, &nArrB, 5);


//Function implementation

void CopyNArr(int* nArr, int* & nArrB, size_t nArrSize) {

// dymanically allocating memory size for array. Assuming 4 byte int size

 nArrB = new int[nArrSize*4];
 size_t itr = 0;
 //Copying values
 for(;itr<nArrSize; itr++)
      nArrB[i] = nArr[i];

}

//After copy nArrB is pointing to first element of 5 element array.


I hope it helped. Write for any further clarification.

1 Comment

Comment "The best way for a beginner would be to use reference to the pointer. You can pass reference to the pointer to your function. Refer to this code snippet:" was meant for 2nd code snippet.
0

You have an array of size 2, but you've created only one element. And that one with a wrong index. Array indexing starts with 0.

The elements should be at h_histogram[0] and h_histogram[1].

1 Comment

sorry I actually have that, fixed it in my original post
0

I am sorry if this answer is completely irrelevant but I am tempted to post it. These is an experiment I have done after seeing your question.

#include<iostream>
using namespace std;
main()
{
int e[2]={0,1};
int *p[2];
int i;
/*
  Printing the array e content using one pointer
  from an array of pointers. Here I am not using p[2]
  at all.
*/
p[1]=e;
cout<<"Elements of e are : \n";
for(i=0;i<2;i++)
{
cout<<*(p[1]+i)<<endl;
/*
In the above line both *((*p)+i) and *(p+i)
won't serve the purpose of printing the array values.
*/
}
/*Printing the array e content using pointer to array*/
cout<<"Elements of e are : \n";
for(i=0;i<2;i++)
{
cout<<*(e+i)<<endl;
}
/*Note that pointer to array is legal but array TO pointer
(don't confuse with array OF pointers) is not.*/
}

Hope this will refresh your understanding.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.