Array of structs

Hello everyone. How can I create an array of structs?
When i run this, I get a segmentation violation.

void test(){

  struct Dataset{
    std::string filename;
    std::string experiment;
    Int_t id_no;
  };

  Dataset cosmicds[5];
}

But if I just create a single struct, instead:

 Dataset cosmicds1 = {"filename1", "experiment1", 1};
 Dataset cosmicds2 = {"filename2", "experiment2", 2};

Everything then works fine. Is there something wrong with the syntax?

Hi,

what did you exactly do? This is valid C++ and works in ROOT 6.05/02.

Danilo

I did exactly what I’ve written.
But it occured to me that maybe ROOT doesn’t like making an array of strings?
If I replace the std::string with something else (Int_t for example) then it works fine.

The problem is that I need the struct to contain strings. What should I do?

Hi,

I tried to copy and paste in the CINT shell and it also worked. What version of ROOT/Cint are you using? Are you feeding the interpreter with these exact lines? How?

Danilo

I’m using ROOT version 5 and I’m giving exactly these lines.
It doesn’t complain when I substitute std::string with Char_t string[40], so for now I’m making it work by successively converting the array of characters into a string when I need it.

What do you mean by “giving”? Cint does not allow function definition in a command-line (neither does Cling, except when in rawInput mode).
It is not a problem for ROOT to load a macro called a.C containing these lines

void test(){

  struct Dataset{
    std::string filename;
    std::string experiment;
    Int_t id_no;
  };

  Dataset cosmicds[5];
}

and calling the test function

.L a.C
test()

and this for ROOT 5.29, head of 5.34 patches branch and master branch (ROOT6).

Cheers,
Danilo

What I mean is that I have a file called “test.C” which looks like the following:

void test(){

  struct Dataset{
    Char_t filename[20];
    Char_t experiment[20];
    Int_t id_no;
  };

  Dataset cosmicds[5];
  strcpy(cosmicds[0].filename,"filename1");
  strcpy(cosmicds[0].experiment,"experiment1");
  cosmicds[0].id_no = 1;

  std::cout << " ---PRINT INFO---" << endl;
  std::cout << " Filename: \t" << cosmicds[0].filename << endl;
  std::cout << " Experiment: \t" << cosmicds[0].experiment << endl;
  std::cout << " ID Number: \t" << cosmicds[0].id_no << endl;
}

when I run root test.C the script runs fine and prints me out the info, but if instead of Char_t I use std::string for the definition of “filename” and “experiment” then I get a segmentation violation.

Hi,

Please post the exact code you run that is causing the crash.

Cheers, Axel.

Hi,

I finally can reproduce the crash: it happens at tear down. It seems to be linked to string destructor which happens via CINT internals. I let Axel comment further about this.
The code is

void test(){

  struct Dataset{
    std::string filename;
    std::string experiment;
    Int_t id_no;
  };

  Dataset cosmicds[5];
  cosmicds[0].filename = "filename1";
  cosmicds[0].experiment = "experiment1";
  cosmicds[0].id_no = 1;

  std::cout << " ---PRINT INFO---" << endl;
  std::cout << " Filename: \t" << cosmicds[0].filename << endl;
  std::cout << " Experiment: \t" << cosmicds[0].experiment << endl;
  std::cout << " ID Number: \t" << cosmicds[0].id_no << endl;
}

Meanwhile, two more facts which could help you move forward:
o The macro is fine with ROOT6
o The macro runs fine with ACLiC (root test.C+)

Cheers,
Danilo

Hi,

Well, if I read sdporzio’s last ost correctly he’s strcpy’ing into a std::string… So let’s have a look at the actual code.

Cheers, Axel.

Hello Alex, the code I wrote in my post (the one with strcpy) is an example of code that I modified in order to work. My initial attempt was to make work the code written by dpiparo, which is the following:

void test(){

  struct Dataset{
    std::string filename;
    std::string experiment;
    Int_t id_no;
  };

  Dataset cosmicds[5];
  cosmicds[0].filename = "filename1";
  cosmicds[0].experiment = "experiment1";
  cosmicds[0].id_no = 1;

  std::cout << " ---PRINT INFO---" << endl;
  std::cout << " Filename: \t" << cosmicds[0].filename << endl;
  std::cout << " Experiment: \t" << cosmicds[0].experiment << endl;
  std::cout << " ID Number: \t" << cosmicds[0].id_no << endl;
}

Hi,

Okay, phew, good - so we are talking about the same code.

In that case I agree with Danilo: please either upgrade ROOT to ROOT 6 which can handle this without problems, or compile your macro by running it as “.x text.C+” (note the ‘+’ at the end). This is a bug in CINT but we will not fix this anymore. Or rather: it is fixed by ROOT 6 :slight_smile:

Cheers, Axel.

Thank you both for your answer!!