Issue with TGCompositeFrame::AddFrame and vectors

I’m working on a GUI to handle some data analysis from a yet-to-be-done experiment and a few of the rows of widgets in the GUI are identical. Until recently, I have just copy and pasted code to make these identical rows, but this doesn’t work if I want the user to be able to add rows on command. My idea is to have a vector of TGHortizontalFrames in order to systematically access the ones I create automatically.

Here is where the problem comes in. This code works:

std::vector<TGHorizontalFrame*>* vecOfRows = new std::vector<TGHorizontalFrame*>();

TGHorizontalFrame* hFrame = new TGHorizontalFrame(myCompositeFrame, 80, 30);
TGLabel* label = new TGLabel(hFrame, "This is a label");
hFrame->AddFrame(label)
vecOfRows->push_back(hFrame);

myCompositeFrame->AddFrame((*vecOfRows)[0])

but this code crashes root:

std::vector<TGHorizontalFrame*>* vecOfRows = new std::vector<TGHorizontalFrame*>();

for (int i = 0; i < 1; i++)
{
TGHorizontalFrame* hFrame = new TGHorizontalFrame(myCompositeFrame, 80, 30);
TGLabel* label = new TGLabel(hFrame, "This is a label");
hFrame->AddFrame(label)
vecOfRows->push_back(hFrame);
}

myCompositeFrame->AddFrame((*vecOfRows)[0])

where the only difference is that I have added in a for loop for 1 iteration. I know from some experimentation that the last line,

is the one responsible for the crash, but I can’t figure out why. I have also found that if I change the line to

it works both in and out of the for loop. Any ideas on what’s going on here? Thanks!

Hi,

I have absolutely no problem running with this code (with ACLiC):

[code]#include “TGFrame.h”
#include “TGLabel.h”
#include

void test_vector()
{
TGMainFrame main = new TGMainFrame(gClient->GetRoot(),200,100);
std::vector<TGHorizontalFrame
>* vecOfRows = new std::vector<TGHorizontalFrame*>();
for (int i = 0; i < 5; i++) {
TGHorizontalFrame* hFrame = new TGHorizontalFrame(main, 80, 30);
TGLabel* label = new TGLabel(hFrame, Form(“This is a label (%d)”, i));
hFrame->AddFrame(label);
vecOfRows->push_back(hFrame);
main->AddFrame((*vecOfRows)[i], new TGLayoutHints(kLHintsCenterX,5,5,5,5));
}
main->MapSubwindows();
main->Layout();
main->Resize(main->GetDefaultSize());
main->MapWindow();
}[/code]On both ROOT v5-34-0-patches and the master (ROOT 6)
So could you post a running macro reproducing the issue?

Cheers, Bertrand.

Here’s a stripped down working version of what I’m working on:

#include <TGClient.h>
#include <TGButton.h>
#include <TGFrame.h>
#include <vector>

void vectorTest()
{
	TGMainFrame* fMain = new TGMainFrame(gClient->GetRoot(), 400, 220);
	TGTab* fTab = new TGTab(fMain, 300, 300);
	TGCompositeFrame* cf = fTab->AddTab("Test Area");

	std::vector<TGHorizontalFrame*>* vecOfRows = new std::vector<TGHorizontalFrame*>();
	for (int i = 0; i < 1; i++)
	{
		TGHorizontalFrame* testHFrame = new TGHorizontalFrame(cf, 80, 30);
		TGLabel* testLabel = new TGLabel(testHFrame, "This is a label");
		testHFrame->AddFrame(testLabel, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 10, 10, 2, 2));
		vecOfRows->push_back(testHFrame);
	}
	cf->AddFrame((*vecOfRows)[0], new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 10, 10, 2, 2));

	fMain->AddFrame(fTab, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
	fMain->MapSubwindows();
	fMain->Resize();
	fMain->SetWindowName("SEU GUI");
	fMain->MapWindow();
}

This code has the same oddity where if I comment out the for loop, it will run fine, but otherwise ROOT will crash. I had been using the code in ROOT 5.34 on windows. I tried the code on the same computer’s ubuntu virtual machine (ROOT 6.02) and the problem vanished there, which is what you experienced.

I find it hard to believe it’s an issue with the operating system, but if it is, do you have any suggestions for a workaround? Thanks!

Hi,

Well, thanks, but your code works just fine with ROOT v5-34-00-patches on Windows (I mostly develop on Windows)… Which exact version of ROOT are you using?

Cheers, Bertrand.

Hmm, that’s quite odd. I’ve tried it on two windows machines so far, and both cases have lead to a crash. One is using

ROOT 5.34/24 (v5-34-24@v5-34-24, win32) and the other has ROOT 5.34/25 (v5-34-24@v5-34-24, win32)

Thanks!

OK, and how do you run the code? Did you try with ACLiC (.x vectorTest.C++)? If not, could you give a try and let me know? In the meanwhile I will try with 5.34.24 and I’ll let you know.

Cheers, Bertrand.

OK, I just tried with ROOT v5.34.24, without any problem:

root [0] .x vectorFrameTest.C 2311237_cint.cxx AutoDict_vector_TGHorizontalFrame___cxx_ACLiC_dict.cxx Creating library C:\Users\bellenot\rootdev\AutoDict_vector_TGHorizontalFrame___cxx.lib and object C:\Users\bellenot\rootdev\AutoDict_vector_TGHorizontalFrame___cxx.exp root [1] One more (important) detail: Are you sure the ROOT binary you are using matches exactly the version of Visual Studio you are using? This is very important if you plan to compile your code (one cannot mix run-time libraries)

Cheers, Bertrand.

I’m not sure how to tell if my Visual Studio version matches the ROOT binary, but only one of the computers I’ve tested it on has Visual Studio. Normally I try

.x vectorTest.cpp

and root crashes pretty much instantly.

Trying it another way, I change the file to vectorTest.C and the following happens:

root [0] .x vectorTest.C++
Info in <TWinNTSystem::ACLiC>: creating shared library C:\root\macros\vectorTest
_C.dll
'cl.exe' is not recognized as an internal or external command,
operable program or batch file.
Error: external preprocessing failed. (0)
!!!Removing C:\root\macros\vectorTest_C_ACLiC_dict.cxx C:\root\macros\vectorTest
_C_ACLiC_dict.h !!!
Error: C:\root\bin\rootcint: error loading headers...
Error in <ACLiC>: Dictionary generation failed!
Info in <ACLiC>: Invoking compiler to check macro's validity
Error: Function vectorTest() is not defined in current scope  (0)
*** Interpreter error recovered ***
root [1]

I wind up with a single extra file in the directory I run it from called vectorTest_C.d.

Thanks for the help!

[quote=“nlupugla”]I’m not sure how to tell if my Visual Studio version matches the ROOT binary[/quote]Well, you know your version of Visual Studio, right? Then you should take the corresponding ROOT binary, as explained on the download page:[quote]Important installation notes:
[ul]
[li]Do not untar in a directory with a name containing blank characters.
[/li][li]Take the release version if performance matters.
[/li][li]If you want to debug your code you need the debug version of Windows (you cannot mix release / debug builds due to a Microsoft restriction).
[/li][li]You need MS VC++ >= 8 for the VC++ 9 build, MS VC++ 10 (2010) for the VC++ 10 build, MS VC++ 11 (2012) for the VC++ 11 build, and MS VC++ 12 (2013) for the VC++ 12 build. For information, there is a no-cost version of Visual Studio 2010.
[/li][li]If you don’t know which one to take: the bold versions are recommended.[/li][/ul][/quote]

[quote=“nlupugla”] root [0] .x vectorTest.C++ Info in <TWinNTSystem::ACLiC>: creating shared library C:\root\macros\vectorTest _C.dll 'cl.exe' is not recognized as an internal or external command, operable program or batch file. Error: external preprocessing failed. (0) !!!Removing C:\root\macros\vectorTest_C_ACLiC_dict.cxx C:\root\macros\vectorTest _C_ACLiC_dict.h !!! Error: C:\root\bin\rootcint: error loading headers... Error in <ACLiC>: Dictionary generation failed! Info in <ACLiC>: Invoking compiler to check macro's validity Error: Function vectorTest() is not defined in current scope (0) *** Interpreter error recovered *** root [1]
[/quote]You have to start from a Developer Command Prompt for Visual Studio (available from the Visual Studio Tools menu), or execute “C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\vcvars32.bat” (the exact location depends on the version of Visual Studio)

Cheers, Bertrand.

Since my code is running fine on your computer, it must be something with my setup as you suggest. However, I don’t really want to muck around with installing ROOT again, so I decided to try using TList as my container instead of std::vector and this has solved the problem. I’m not really sure why this works, but if you have any thoughts I would be interested. Anyway, thanks for the help!

[quote=“nlupugla”]Since my code is running fine on your computer, it must be something with my setup as you suggest. However, I don’t really want to muck around with installing ROOT again, so I decided to try using TList as my container instead of std::vector and this has solved the problem. I’m not really sure why this works, but if you have any thoughts I would be interested.[/quote]That might be a version issue. Can you tell me which version of Visual Studio you are using?

[quote=“nlupugla”]Anyway, thanks for the help![/quote]You’re very welcome! :slight_smile:

One of the computers doesn’t have VS installed and the other has the following:

Microsoft Visual Studio 2010 Professional
Version 10.0.30319.1 RTMRel

OK, thanks! I’ll try with Visual Studio 2010 and I’ll let you know.

Cheers, Bertrand.

OK, problem understood: you have to start ROOT from a Visual Studio environment, to let cint create the automatic dictionary of std::vector<TGHorizontalFrame*>. Sorry for not finding this immediately, but I always work in such environment…

Cheers, Bertrand.

Ahh, I see, thanks!