Initialize variables in setup() for use in draw()

Hello,
This is a very basic question but if I would be glad to receive some help on understanding this.
My ofApp.cpp is like this:

void ofApp::setup(){
	tcpComObject.setup();
}
// and so on for all of update, draw, etc...

So, in my seperate cpp files corresponding to the class:

//tcpCom.cpp (only parts of interest)
void tcpCom::setup(){
	std::vector<std::string> cmdVector(8, "a");
	ofLog() << "cmdVector size: "<< cmdVector.size();
	ofLog() << "cmdVector capacity: "<< cmdVector.capacity()<< endl;
}
void tcpCom::draw(){
	ofDrawBitmapString( "cmdVector size: " + ofToString(cmdVector.size()) + " cap: " + ofToString(cmdVector.capacity()), 15, 30);

When I run the release, I have this output on the console:
[notice ] cmdVector size: 8
[notice ] cmdVector capacity: 8

But what is drawn is :
cmdVector size: 0 cap: 0

That’s where I’m lost, so here are my two questions:
Are those variables different when they are in different functions ? I know they can be global or local, but I thought the setup function was there to initialize variables. Is there a need to initialize variables, where ?

Thanks. Tell me if this should go to StackOverflow.com preferably, but I like it in here.

Hi, I assume you have a cmdVector declared in the header file, right? Otherwise draw() would fail.

The one found in setup is a different (local) cmdVector, which you initialize and then is lost when the function execution ends. It’s local because you included again its type std::vector<std::string>.

Probably you wanted to do this in setup:

cmdVector.assign(8, "a");

Setup is a great place to initialize variables :slight_smile:

Two more ways to initialize your vector in the header file:

// 3 strings in the vector
std::vector<std::string> cmdVector {"a", "b", "c"}; 

// 8 repeated strings in the vector
std::vector<std::string> cmdVector {8, "s"};

Oh !
Alright ! I didn’t notice that ! I guess in the header it is quicker and more straight forward then !
Thank you @hamoid for this, but I may have to ask you another question, in order to know if this init is worth anything at all:

In my code I have then:

void tcpCom::update(){ //short version...
	cmdRx(str); // str is a string of words containing spaces
}
void tcpCom::cmdRx(const string& rxString){
	cmdVector = ofSplitString(rxString, " ", true); // each word in an element
	//use the vector cmdVector
}

I notice that the size and capacity of the vector changes when this function is called. Was it worth it to initialize ? And if yes, because I don’t know how much elements will I ever need, should I initialize with the maximum number of elements ever expected ?

Maybe it was not worth initializing, as it would do that anyway the first time the string is split. But I’m just assuming after 2 or 3 years using C++.

If performance is an issue I would measure different options and choose the fastest. The most performant option will probably depend on the size and type of data you are dealing with.

Yes that makes sense.
I was a bit afraid of memory leaks, as I understand it, but there is no errors or anything, maybe the compiler takes care of it…
Thanks anyway !

If you’re concerned about memory leaks you could let your program run for 15 minutes and observe it’s memory usage, see if it continuously goes up.

You could also work with a data structure with fixed size, maybe a 2D array with words and letters. The words “axis” would have the longest possible amount of words in a sentence, and the “letters” axis would have the longest possible word size. Then you could write your own split function that sets letters in this 2D array. But it’s probably more likely to make a mistake in such an implementation (even if it’s a good exercise) than encountering a bug in std::string, std::vector or ofSplitString :slight_smile:

1 Like

there’s no leaks there, you are just overwriting a vector (cmdVector) with another (the one returned by ofSplitString). When doing that the first vector will free it’s memory automatically

Thank you for those infos. Yes I see that std::vector is pretty powerful and automatically resize() when changed.