Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Program organizattion question in c++
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Sun Mar 10, 2013 3:52 am    Post subject: Program organizattion question in c++ Reply with quote

In the main function of my program, an instance of a certain kind calls one of it's methods.
In this method, another method from that instance is called, and from this second method a third one is also called. After two executions of the third function, I gather enough information from a file
to fill in a structure of certain kind. So far so good. This filling is done in the second method. After it's done, the structure is added to a vector container. Then the second method keep running a loop and gathering information to fill in another structures, and these keep being added to the vector.

The problem it is that I will need to use the information from these structures far ahead in the program execution, and soon the second method is over, these structures cease to exist, since they are declared locally and their scope has just ended. So I end with a vector full of garbage references.

So what is the best choice for a case like this? I can transfer part of the logic of these methods to the main function, so I will never run out of scope before the program finishes, but I really don't like this solution because: 1) Main is used basically as a collection of actions of several instances with very little logical in it. 2) The algorithm I created to extract information from a file is well organized being distributed in these three methods, a rewriting of it possibly is not going to be as elegant.

What I would really like would be to have something like vector that accepted pointers to dynamic memory, so the structures would keep existing after the method ended and them in the program end I would release the pointers stored in the hypothetical vector.

Any suggestions?

EDIT:

I experimented modifying the algorithm to run it partly in main and besides making the program uglier, it really doesn't solve my problem, since the structure is still being declared inside a loop, and when the loop finishes there will still be garbage in the vector.

Declaring structure variables outside the loop is not possible since I don't know how many I will need. What I really need is an vector that work with copies and not references.
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21489

PostPosted: Sun Mar 10, 2013 4:45 am    Post subject: Reply with quote

You can use boost::ptr_vector for this purpose. You could also change the definition of the object being placed in the vector, so that it is self-contained. In my opinion, this is a good idea anyway. Most users would be surprised to find that they can insert an instance of your object into a vector and have the object become partially invalid while the vector is still valid.
Back to top
View user's profile Send private message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Sun Mar 10, 2013 4:50 am    Post subject: Reply with quote

I will check boost::ptr_vector as soon as I have time.

What do you mean by "self-contained" exactly? You think it might be the best solution?

P:S: Check my edition of the first post
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21489

PostPosted: Sun Mar 10, 2013 4:18 pm    Post subject: Reply with quote

I think you found a way to do something bad. Vectors do work with copies, not references. They copy whatever you give them, and maintain the copy for you. If you have managed to have stale data, that suggests you are forcing the vector to accept a reference instead. Perhaps you made a std::vector<T*> when you should have used a std::vector<T>.

By self-contained, I mean that a copy of your object should never become partially invalid as a result of local variables expiring. Your object should either embed or have a strong pointer to any resources it needs. You could mix these techniques if you have some sub-objects that are cheap to embed and others which ought to be on the heap.

Seeing a minimal sample of your code would help us help you.
Back to top
View user's profile Send private message
dmitchell
Veteran
Veteran


Joined: 17 May 2003
Posts: 1159
Location: Austin, Texas

PostPosted: Tue Mar 12, 2013 10:06 pm    Post subject: Re: Program organizattion question in c++ Reply with quote

One possibility is that the structure (struct) he mentions doesn't have a proper copy constructor and assignment operator.
_________________
Your argument is invalid.
Back to top
View user's profile Send private message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Wed Mar 13, 2013 6:33 am    Post subject: Reply with quote

Ok here are some code excerpts:
Code:
while (line != "") {
     getline (fileReader,line);
     if (line[0] != ' ')
       continue;
     getLineValue2 (lineNumbers, scene, lineNumbersIndex);
     getLineValue2Counter++;
     if (getLineValue2Counter==2) {
       Material material;
       getLineValue2Counter=0;
       lineNumbersIndex=0;
       material.color.red = lineNumbers[0];
       material.color.green = lineNumbers[1];
       material.color.blue = lineNumbers[2];
       material.reflection = lineNumbers[3];
       scene.addMaterial (material);


Code:
struct Material {
  Color color;
  float reflection;
};


Code:
inline void addMaterial (const Material &material) { materialContainer.push_back (material); }


Code:
 private:
    std::vector <Material> materialContainer;


Basically I don't know how many "material" structures I will find declared in the text file so I want to create it as needed, fill its members with the data from an array, data that I collect from a function, and then add it to the vector container that will exist until program termination
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21489

PostPosted: Wed Mar 13, 2013 10:26 pm    Post subject: Reply with quote

I wanted you to provide us with enough code that we could reproduce the problem. The provided code is not even a full block, so we can only speculate on what your code does in the portions not shown.
Back to top
View user's profile Send private message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Fri Mar 15, 2013 6:39 am    Post subject: Reply with quote

What parts shall I post? I thought the only relevant parts were these
Back to top
View user's profile Send private message
dmitchell
Veteran
Veteran


Joined: 17 May 2003
Posts: 1159
Location: Austin, Texas

PostPosted: Fri Mar 15, 2013 8:51 am    Post subject: Reply with quote

coltson:
while (line != "") {
     getline (fileReader,line);
     if (line[0] != ' ')
       continue;
     getLineValue2 (lineNumbers, scene, lineNumbersIndex);
     getLineValue2Counter++;
     if (getLineValue2Counter==2) {
       Material material;
       getLineValue2Counter=0;
       lineNumbersIndex=0;
       material.color.red = lineNumbers[0];
       material.color.green = lineNumbers[1];
       material.color.blue = lineNumbers[2];
       material.reflection = lineNumbers[3];
       scene.addMaterial (material);

The structure of this loop looks highly suspicious to me. My guess: the loop doesn't terminate when you think it does, and you end up with garbage in line and lineNumbers, resulting in garbage Material and the end of the vector.
_________________
Your argument is invalid.
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21489

PostPosted: Fri Mar 15, 2013 10:53 pm    Post subject: Reply with quote

coltson wrote:
What parts shall I post? I thought the only relevant parts were these
The portion you posted is not a valid C program. If I copy everything you posted into a file, give it a .c extension, and run gcc on it, I get compilation errors, because portions of the program are missing.
Back to top
View user's profile Send private message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Sat Mar 16, 2013 7:02 pm    Post subject: Reply with quote

dmitchell wrote:

The structure of this loop looks highly suspicious to me. My guess: the loop doesn't terminate when you think it does, and you end up with garbage in line and lineNumbers, resulting in garbage Material and the end of the vector.


Well, your guess is wrong.

Quote:
The portion you posted is not a valid C program. If I copy everything you posted into a file, give it a .c extension, and run gcc on it, I get compilation errors, because portions of the program are missing.


Well, full source is too big to put here, but something I can do is to make a new program copying only the relevant part into a single file. I will do that and post here
Back to top
View user's profile Send private message
dmitchell
Veteran
Veteran


Joined: 17 May 2003
Posts: 1159
Location: Austin, Texas

PostPosted: Sun Mar 17, 2013 9:22 am    Post subject: Reply with quote

coltson wrote:
Well, your guess is wrong.

Very possible. What is the type of lineNumbers and material.color.red?
_________________
Your argument is invalid.
Back to top
View user's profile Send private message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Sat Mar 23, 2013 5:15 am    Post subject: Reply with quote

Quote:
Very possible. What is the type of lineNumbers and material.color.red


float array and float.

I am with a bziped file with the code. There is a way to attach it to a message?
Back to top
View user's profile Send private message
dmitchell
Veteran
Veteran


Joined: 17 May 2003
Posts: 1159
Location: Austin, Texas

PostPosted: Sun Mar 24, 2013 4:09 am    Post subject: Reply with quote

coltson wrote:
I am with a bziped file with the code. There is a way to attach it to a message?

I don't think so. Upload it somewhere (example) and post a link.
_________________
Your argument is invalid.
Back to top
View user's profile Send private message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Tue Mar 26, 2013 7:13 am    Post subject: Reply with quote

Ok, here is the file: http://ompldr.org/vaHZ4ag/test.tar.bz2

To run it, execute the file TEST, passing as parameter the file scene.ini.

To recompile it, save the content of the altered file and run test.sh

By default, It will print the content that was read from the file in the screen.

This is happening in the TextManager.cpp file, in the end of the getMaterialData method (the third method).

This is working as expected. However in the scanFile method (the first one), the one that calls getMaterialData, just after it's invocation, there is a lot of commented out cout's whose purpose is to show up the problem. These cout's are basically the same that press the vector content in the screen, running just after the last cout sequence with nothing between them. The only difference being that they are in a different method. If uncommented and the program gets recompiled, when the program runs again it will press: "segmentation fault" on the screen, like the content stored in vector run out of scope.
Back to top
View user's profile Send private message
dmitchell
Veteran
Veteran


Joined: 17 May 2003
Posts: 1159
Location: Austin, Texas

PostPosted: Tue Mar 26, 2013 3:47 pm    Post subject: Reply with quote

coltson wrote:
Ok, here is the file: http://ompldr.org/vaHZ4ag/test.tar.bz2

To run it, execute the file TEST, passing as parameter the file scene.ini.

To recompile it, save the content of the altered file and run test.sh

By default, It will print the content that was read from the file in the screen.

This is happening in the TextManager.cpp file, in the end of the getMaterialData method (the third method).

This is working as expected. However in the scanFile method (the first one), the one that calls getMaterialData, just after it's invocation, there is a lot of commented out cout's whose purpose is to show up the problem. These cout's are basically the same that press the vector content in the screen, running just after the last cout sequence with nothing between them. The only difference being that they are in a different method. If uncommented and the program gets recompiled, when the program runs again it will press: "segmentation fault" on the screen, like the content stored in vector run out of scope.

You forgot to use braces. You have:

Code:
else if (line == "[Material]")
  getMaterialData (scene);
  cout << scene.materialContainer[0].color.red << endl;
  ...
  cout << scene.materialContainer[2].reflection << endl;

Only getMaterialData is executed conditionally. The cout statements are executed every iteration of the while loop, including before getMaterialData (after getImageData).

Also, instead of building up integers by reading one digit at a time from a string, I suggest you look at std::stringstream.
_________________
Your argument is invalid.
Back to top
View user's profile Send private message
coltson
n00b
n00b


Joined: 15 Oct 2005
Posts: 54

PostPosted: Fri Mar 29, 2013 6:37 am    Post subject: Reply with quote

Thanks.

When I was doing this part of the program, I read about stringstream and tested it, but since it converts the entire string it wasn't useful.
So I decided to write my own algorithm could be easier than search other functions that could help stringstream to accomplish my goals.
Now that I already did it, do you think it still worth to research that information ?
Back to top
View user's profile Send private message
dmitchell
Veteran
Veteran


Joined: 17 May 2003
Posts: 1159
Location: Austin, Texas

PostPosted: Fri Mar 29, 2013 4:47 pm    Post subject: Reply with quote

coltson wrote:
When I was doing this part of the program, I read about stringstream and tested it, but since it converts the entire string it wasn't useful.
So I decided to write my own algorithm could be easier than search other functions that could help stringstream to accomplish my goals.
Now that I already did it, do you think it still worth to research that information ?

Yes, but not a high priority. Add it to your TODO file.

You might consider using the regular expression library, which would look something like this.

Code:
#include <regex>
#include <string>
#include <vector>

std::vector<float> getnumbers(std::string const& str)
{
  static std::regex const numbers{"[+-]?(\\d*\\.)?\\d+"};
  std::vector<float> result;
  for (std::sregex_iterator it{str.begin(), str.end(), numbers}, end; it != end; ++it)
    result.push_back(std::stof(it->str()));
  return result;
}

_________________
Your argument is invalid.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum