By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,987 Members | 967 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,987 IT Pros & Developers. It's quick & easy.

smart pointers for c++

P: 14
what's a good smart pointer to use for c++?? I want them for use in a vector of pointers....
Apr 11 '06 #1
Share this Question
Share on Google+
10 Replies


Banfa
Expert Mod 5K+
P: 8,916
This question doesn't really make sense.

What do you mean by the term "smart pointer"?

A vector of pointers to what?

What you should try to do is avoid using a vector of void pointers (void *). They may sound like a good idea but the strong typing of C++ is useful in ensuring a rigerously written working program. Using void * just gets round this.

So what are the pointers in your vector pointing at? Is it a specific type, like int, in which case you can use int *, or a class or structure in which case you can, again, just use a pointer to that class or structure.

Or do you need to point to a variety of different classes. In this case you should see if there is some sort of link between the classes that allows you to declare the structures in a hierarchy and declare you vector with pointers to the base class in the hierarchy.

If none of that will do the trick then you may have to declare a union, however since you will need to be able to tell which item in the union is the one in use then you will probably have to do something like declare an enum identifying the union member in use and a structure containing an enum and a union entry and the vector with pointers to this structure.
Apr 11 '06 #2

P: 14
yeah, the pointers in the vector are pointing to class objects. there are different constructors in the class to initialize class objects with a different number of pointers. but all objects being pointed to are essentially the same, yeah.

I can't ever delete any of the objects, and I think the problem lies with the pointers I use to new them. the pointers to the objects are shuffled around in the vectors quite a bit, and I'm not sure that the vector is the best at handling pointers...
Apr 12 '06 #3

Banfa
Expert Mod 5K+
P: 8,916
If it is always the same class why use pointers at all just have a vector of classes like so

Expand|Select|Wrap|Line Numbers
  1. #include <string>
  2. #include <vector>
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. class Colour
  8. {
  9. private:
  10.     string name;
  11.     unsigned char red;
  12.     unsigned char green;
  13.     unsigned char blue;
  14.  
  15. public:
  16.     Colour()
  17.     {
  18.         name="black";
  19.         red = 0;
  20.         green = 0;
  21.         blue = 0;
  22.     }
  23.  
  24.     Colour(char *n, unsigned char r, unsigned char g, unsigned char b )
  25.     {
  26.         name=n;
  27.         red = r;
  28.         green = g;
  29.         blue = b;
  30.     }
  31.  
  32.     inline operator const char * (void) const
  33.     {
  34.         return name.c_str();
  35.     }
  36.  
  37.     unsigned long GetColour(void)
  38.     {
  39.         return ((unsigned long)red<<16)|((unsigned long)green<<8)|blue;
  40.     }
  41. };
  42.  
  43. static void vectorWork(void)
  44. {
  45.     int i;
  46.     vector <Colour> v1;
  47.  
  48.     v1.resize(10);
  49.  
  50.     for(i=0; i<v1.size(); i++)
  51.     {
  52.         cout << i << ": " << (const char *)v1[i] << endl;
  53.     }
  54.  
  55.     cout << endl;
  56.  
  57.     v1[0] = Colour("Red", 255, 0, 0);
  58.     v1[1] = Colour("Green", 0, 255, 0);
  59.     v1[2] = Colour("Blue", 0, 0, 255);
  60.  
  61.     v1[3] = Colour("Cyan", 0, 255, 255);
  62.     v1[4] = Colour("Magenta", 255, 255, 0);
  63.      v1[5] = Colour("Yellow", 255, 0, 255);
  64.  
  65.     v1[6] = Colour("White", 255, 255, 255);
  66.     v1[7] = Colour("Black", 0, 0, 0);
  67.  
  68.     v1[8] = Colour("Grey", 192, 192, 192);
  69.     v1[9] = Colour("Dark Grey", 128, 128, 128);
  70.  
  71.     for(i=0; i<v1.size(); i++)
  72.     {
  73.         cout << i << ": " << (const char *)v1[i] << endl;
  74.     }
  75.  
  76.     cout << endl;
  77.  
  78.     v1.erase( v1.begin( ) + 6, v1.begin( ) + 7 );
  79.  
  80.     for(i=0; i<v1.size(); i++)
  81.     {
  82.         cout << i << ": " << (const char *)v1[i] << endl;
  83.     }
  84.  
  85.     cout << endl;
  86. }
  87.  
Apr 12 '06 #4

Banfa
Expert Mod 5K+
P: 8,916
P.S. You could post your non-working code rather than leave me to guess what the error is.
Apr 12 '06 #5

P: 14
ok, that didn't work, here it really is.

Expand|Select|Wrap|Line Numbers
  1. #include "stdafx.h"
  2.  
  3. #include <iostream.h>
  4. #include <fstream>
  5. #include <iomanip.h>
  6. #include <deque>
  7. #include <vector>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <time.h>
  11. #include <math.h>
  12. #include <cassert>
  13.  
  14. using namespace std;
  15.  
  16. void main()
  17. {
  18.     //initialize random number generator
  19.     //srand(time(NULL));
  20.     srand(1247365);
  21.  
  22.     //variable to keep track of the total interbranch weight
  23.     double TIBW = 0;
  24.  
  25.     //variable to keep track of the total number of interbranch spaces
  26.     double IBC = 0;
  27.  
  28.     //variable to keep track of the number of generations in each polymer and the average number of generations of the final solution
  29.     double gen = 0;
  30.     double gentot = 0;
  31.  
  32.     //initialize variables to account for the number of each type of monomer
  33.     int addnum = 0;
  34.     int branchnum = 0;
  35.     int chains = 0;
  36.     int ochains =0;
  37.     double addprob = 0;
  38.     double branchprob1 = 0;
  39.     double branchprob2 = 0;
  40.     double alpha = 0;
  41.  
  42.     //initialize the variable for labelling uniqueness in original chains
  43.     int namenumber = -1;
  44.  
  45.     //counters to keep track of the iterator positions in the deques
  46.     int nucounter;
  47.     int elecounter;
  48.  
  49.     //counter for number of iterations, debuggins
  50.     int iter = 0;
  51.  
  52.     //obtains user input for various values needed
  53.     input(chains, addnum, branchnum, addprob, branchprob1, branchprob2, alpha);
  54.  
  55.     //initialize the queue to hold pointers to the polymer chain ends
  56.     vector<monomer*> nucleophiles;
  57.     //initialize the queue to hold pointer to the reactive monomers
  58.     vector<monomer*> electrophiles;
  59.     //initialize the vector to hold the finished polymers
  60.     vector<monomer*> polymers;
  61.  
  62.     //initialize [chains] number of original polymer chains and push onto nucleophiles
  63.     initializechains(nucleophiles, chains, namenumber);
  64.  
  65.     //initialize the variable for labelling uniqueness in monomers
  66.     namenumber = 1;
  67.  
  68.     //initialize [branchnum] number of branching monomers and push onto electrophiles
  69.     initializebranchmons(electrophiles, branchnum, namenumber);
  70.  
  71.     //initialize [addnum] number of additive monomers and push onto electrophiles
  72.     initializeaddmons(electrophiles, addnum, namenumber);
  73.  
  74.     //loop to build the polymers
  75.     while(nucleophiles.size()!=0)// this will not be needed when the kinetics are being used
  76.     {
  77.         //reinitialize counters
  78.         nucounter = 0;
  79.         elecounter = 0;
  80.  
  81.         if(!electrophiles.empty())//if the elecrophiles queue is not empty there are still more monomers to react
  82.         {    
  83.             determine_electrophile(electrophiles, elecounter, addprob, branchprob1, branchprob2, alpha);
  84.             determine_nucleophile(nucleophiles, nucounter, alpha, iter);
  85.  
  86.             addmonomer(nucleophiles, electrophiles, nucounter, elecounter, addprob, branchprob1, branchprob2, alpha, iter);
  87.         }
  88.         else//if the electrophiles queue is empty we add more monomers to react
  89.         {
  90.             initializeaddmons(electrophiles, addnum, namenumber);
  91.             initializebranchmons(electrophiles, branchnum, namenumber);
  92.         }
  93.         iter = iter+1;
  94.     }
  95.  
  96.     cout<< endl<<"Polymer is done building." << endl<<endl;
  97. }
  98. void initializechains(vector<monomer*>& nucs, int& chainum, int& namenum)
  99. {
  100.     if(chainum > 0)
  101.     {
  102.         for(int i=0; i< chainum; i++)
  103.         {    
  104.             //pointers for the initialization of the correct monomer
  105.             monomer* pointforward = NULL;
  106.  
  107.             //creating and initializing the monomer
  108.             monomer* monomeri = new monomer(pointforward, namenum);
  109.             monomeri->namenumber = namenum; 
  110.  
  111.             //inserting the monomer onto its vector
  112.             nucs.insert(nucs.begin(), monomeri);
  113.             //nucs.push_back(monomeri);
  114.             //nucs.push_back(monomer(pointforward, namenum));
  115.  
  116.             //deleting pointers
  117.             delete pointforward;
  118.             monomeri = NULL;
  119.  
  120.             //resetting namenumber
  121.             namenum = namenum - 1;
  122.         }
  123.  
  124.     }
  125.     else
  126.     {
  127.         cout << "there are no original chains to initialize." <<endl;
  128.     }
  129.  
  130. }
  131.  
  132. void initializeaddmons(vector<monomer*>& elecs, int& adds, int& namenum)
  133. {
  134.     if(adds > 0)
  135.     {
  136.         for(int i =0; i<adds; i++)
  137.         {
  138.             //pointers for the initialization of the correct monomer
  139.             monomer* pointforward = NULL;
  140.             monomer* pointbackward = NULL;
  141.  
  142.             //creating and initializing the monomer
  143.             monomer* addmonomeri = new monomer(pointforward, pointbackward);//**
  144.             addmonomeri->namenumber = namenum;
  145.  
  146.             //inserting the monomer onto its vector
  147.             elecs.insert(elecs.begin(), addmonomeri);
  148.             //elecs.push_back(addmonomeri);
  149.  
  150.             //deleting pointers
  151.             delete pointforward;
  152.             delete pointbackward;
  153.             addmonomeri = NULL;
  154.  
  155.             //resetting namenumber
  156.             namenum = namenum + 1;
  157.         }
  158.     }
  159.     else
  160.     {
  161.         //cout << "there are no additive monomers to initialize." <<endl;
  162.     }
  163.  
  164. }
  165.  
  166. void initializebranchmons(vector<monomer*>& elecs, int& branchers, int& namenum)
  167. {
  168.     if(branchers > 0)
  169.     {
  170.         for(int i = 0; i<branchers; i++)
  171.         {
  172.             //pointers for the initialization of the correct monomer
  173.             monomer* pointforward = NULL;
  174.             monomer* pointbackward = NULL;
  175.             monomer* pointbranch = NULL;
  176.  
  177.             //creating and initializing the monomer
  178.             monomer* branchmoni =  new monomer(pointforward, pointbackward, pointbranch);
  179.             branchmoni->namenumber = namenum;
  180.  
  181.             //inserting the monomer onto its vector
  182.             elecs.insert(elecs.begin(), branchmoni);
  183.             //elecs.push_back(branchmoni);
  184.  
  185.             //deleting pointers
  186.             delete pointforward;
  187.             delete pointbackward;
  188.             delete pointbranch;
  189.             branchmoni = NULL;
  190.  
  191.             //resetting namenumber
  192.             namenum = namenum + 1;
  193.         }
  194.     }
  195.     else
  196.     {
  197.         //cout << "there are no branching monomers to initialize." <<endl;
  198.     }
  199.  
  200. }
  201.  
  202. void addmonomer(vector<monomer*>& nucs, vector<monomer*>& elecs, int& nucount, int& elecount, double addrate_4, double branchrate1_4, double branchrate2_4, double alpha_6, int iter3)
  203. {
  204.     //checks
  205.     //int elesizecheck = elecs.size();
  206.     //int nucsizecheck = nucs.size();
  207.  
  208.     //declare the iterators
  209.     vector<monomer*>::iterator nuchooser = nucs.begin();
  210.     vector<monomer*>::iterator elechooser = elecs.begin();
  211.  
  212.     //set the iterators
  213.     for(int nucount2 = 0; nucount2 != nucount; ++nucount2)
  214.     {
  215.         ++nuchooser;
  216.     }
  217.  
  218.     for(int elecount2 = 0; elecount2 != elecount; ++elecount2)
  219.     {
  220.         ++elechooser;
  221.     }
  222.  
  223.     //see if the nucleophile and electrophile are in the same polymer
  224.     bool loopy = 0;
  225.     looper(nucs[nucount], loopy, elecs[elecount]->namenumber);
  226.     if(elecs.size()==1 && nucs.size()==1 && (elecs[elecount]->namenumber == nucs[nucount]->namenumber || loopy ==1))
  227.     {
  228.         nucs.erase(nuchooser);
  229.     }
  230.     else
  231.     {
  232.  
  233.     //protection against a monomer reacting with itself
  234.     if(nucs.size()==1 && elecs.size()>1 && (elecs[elecount]->namenumber == nucs[nucount]->namenumber || loopy ==1))
  235.     {
  236.         while(elecs[elecount]->namenumber == nucs[nucount]->namenumber)
  237.         {
  238.             determine_electrophile(elecs, elecount, addrate_4, branchrate1_4, branchrate2_4, alpha_6);
  239.         }
  240.  
  241.         //reset the electrophile iterator
  242.         elechooser = elecs.begin();
  243.  
  244.         for(int elecount2 = 0; elecount2 != elecount; ++elecount2)
  245.         {
  246.             ++elechooser;
  247.         }
  248.     }
  249.     else if(elecs.size()==1 && nucs.size()>1 && (elecs[elecount]->namenumber == nucs[nucount]->namenumber || loopy ==1))
  250.     {
  251.         while(elecs[elecount]->namenumber == nucs[nucount]->namenumber)
  252.         {
  253.             determine_nucleophile(nucs, nucount, alpha_6, iter3);
  254.         }
  255.  
  256.         //reset the nucleophile iterator
  257.         nuchooser = nucs.begin();
  258.  
  259.         for(int nucount2 = 0; nucount2 != nucount; ++nucount2)
  260.         {
  261.             ++nuchooser;
  262.         }
  263.     }
  264.  
  265.     //additive monomer reaction
  266.     if(elecs[elecount]->tag == 2)
  267.     {
  268.         //reaction
  269.         nucs[nucount]->next = &*(elecs[elecount]);
  270.         elecs[elecount]->previous = &*(nucs[nucount]);
  271.  
  272.         //reset the molecular weight, number of nodes, number of original chains
  273.         elecs[elecount]->molweight = elecs[elecount]->molweight + nucs[nucount]->molweight;
  274.         elecs[elecount]->nodes = elecs[elecount]->nodes + nucs[nucount]->nodes;
  275.         elecs[elecount]->originalchains = elecs[elecount]->originalchains + nucs[nucount]->originalchains;
  276.  
  277.         //vector shuffling
  278.         nuchooser = nucs.erase(nuchooser);
  279.         nuchooser = nucs.insert(nuchooser, elecs[elecount]);
  280.         elechooser = elecs.erase(elechooser);
  281.     }
  282.  
  283.     //branching monomer reaction
  284.     else if(elecs[elecount]->tag == 3)
  285.     {    
  286.         //fast site
  287.         if(elecs[elecount]->nextbranchtag == 2)
  288.         {
  289.             bool loopy2 = 0;
  290.             looper(nucs[nucount], loopy2, elecs[elecount]->namenumber);
  291.  
  292.             if(loopy2==0)
  293.             {            
  294.             //set the monomers fast site as reacted
  295.             elecs[elecount]->branchfull = 1;
  296.  
  297.             //reaction
  298.             nucs[nucount]->next = &*(elecs[elecount]);
  299.             elecs[elecount]->branch = &*(nucs[nucount]);
  300.  
  301.             //reset the molecular weight, number of nodes, number of original chains
  302.             elecs[elecount]->molweight = elecs[elecount]->molweight + nucs[nucount]->molweight;
  303.             elecs[elecount]->nodes = elecs[elecount]->nodes + nucs[nucount]->nodes;
  304.             elecs[elecount]->originalchains = elecs[elecount]->originalchains + nucs[nucount]->originalchains;
  305.  
  306.             //vector shuffling
  307.             nuchooser = nucs.erase(nuchooser);
  308.             //if electrophile has no electrophilic sites left
  309.             if(elecs[elecount]->nextfull)
  310.                 elechooser = elecs.erase(elechooser);
  311.             }
  312.         }
  313.  
  314.         //slow site
  315.         else if(elecs[elecount]->nextbranchtag == 1)
  316.         {    
  317.             //set the monomers slowsite as reacted
  318.             elecs[elecount]->nextfull = 1;
  319.  
  320.             //reaction
  321.             elecs[elecount]->previous = &*(nucs[nucount]);
  322.             nucs[nucount]->next = &*(elecs[elecount]);
  323.  
  324.             //reset the molecular weight, number of nodes, number of original chains
  325.             elecs[elecount]->molweight = elecs[elecount]->molweight + nucs[nucount]->molweight;
  326.             elecs[elecount]->nodes = elecs[elecount]->nodes + nucs[nucount]->nodes;
  327.             elecs[elecount]->originalchains = elecs[elecount]->originalchains + nucs[nucount]->originalchains;
  328.  
  329.             //vector shuffling
  330.             nuchooser = nucs.erase(nuchooser);
  331.             nuchooser = nucs.insert(nuchooser, elecs[elecount]);
  332.             //electrophile has no electrophilic sites left
  333.             if(elecs[elecount]->branchfull)
  334.                 elechooser = elecs.erase(elechooser);
  335.  
  336.         }
  337.     }
  338.     }
  339. }
  340.  
Apr 12 '06 #6

P: 14
so i had to cut out a lot of the code to make it less than 10000 characters long, but i included the parts where I am newing stuff and putting it onto the vectors and the parts where I am shuffling elements(pointers) around in the vectors.

when I think about it, the reason I used vectors of pointers is because i couldn't find out how to put my newed objects onto a vector of class objects....
Apr 12 '06 #7

Banfa
Expert Mod 5K+
P: 8,916
Right I begin to see your problems, my "Colour" example is clear not complex enough to be comapred to what you are trying to do.

I have some comments and some questions:

I do not know the structure of you class monomer however I infer from how you have used it that contains some (at least 3?) pointers to other instances of itself and that you have a constructor that accepts setup values for these pointers a bit like

Expand|Select|Wrap|Line Numbers
  1. class monomer
  2. {
  3. public:
  4.     monomer *pointforward;
  5.     monomer *pointbackward;
  6.     monomer *pointbranch;
  7.  
  8.     // other members here
  9.  
  10.     monomer(monomer *pforward=NULL, 
  11.                  monomer *pbackward=NULL, 
  12.                  monomer *pbranch=NULL)
  13.     {
  14.         pointforward = pforward;
  15.         pointbackward = pbackward;
  16.         pointbranch = pbranch;
  17.  
  18.        // Initialise other members
  19.     }
  20. }
  21.  
On this basis I have the following questions
  1. You set up 3 monomer * vectors. Can a given instance of the monomer class appear in more than 1 of these vectors?
  2. Each monomer class contains pointers to other instances of the monomer class. Is it possible for 2 separate instances on the monomer class to end up with there internal pointers pointing to the same 3rd instance of the monomer class?
  3. Is it possible for an instance of a monomer class to end up in a vector and being pointed to by another instance of the monomer class.

If your answer to question 1 is YES then you definately need to be using vectors of pointers, however if it is NO then you may be able to use vectors of classes (which would probably be better as the vector then deals with the destruction of the instance for you) especially if your answer to question 3 is also NO.

Now lets examine a small fragment of your posted code

Expand|Select|Wrap|Line Numbers
  1. void initializechains(vector<monomer*>& nucs, int& chainum, int& namenum)
  2. {
  3.     if(chainum > 0)
  4.     {
  5.         for(int i=0; i< chainum; i++)
  6.         {    
  7.             //pointers for the initialization of the correct monomer
  8.             monomer* pointforward = NULL;
  9.  
  10. // Some code missing here ???
  11.  
  12.             //creating and initializing the monomer
  13.             monomer* monomeri = new monomer(pointforward, namenum);
  14.             monomeri->namenumber = namenum; 
  15.  
  16.             //inserting the monomer onto its vector
  17.             nucs.insert(nucs.begin(), monomeri);
  18.             //nucs.push_back(monomeri);
  19.             //nucs.push_back(monomer(pointforward, namenum));
  20.  
  21.             //deleting pointers
  22.             delete pointforward;
  23.             monomeri = NULL;
  24.  
  25.             //resetting namenumber
  26.             namenum = namenum - 1;
  27.         }
  28.  
  29.     }
  30.     else
  31.     {
  32.         cout << "there are no original chains to initialize." <<endl;
  33.     }
  34.  
  35. }
  36.  
There are at least 2 other similar examples of this in your code.

I do not believe that this piece of code can possibly work in the way you intend it to. First assuming that there is no code missing at the indicated point then with reference to the variable pointforward the code
  1. Sets it's value to NULL:
    monomer* pointforward = NULL;
  2. Uses it in the constrcution of another monomer class
    monomer* monomeri = new monomer(pointforward, namenum);
  3. And finally deletes it:
    delete pointforward;

The the code is as it is posted then in step C it is deleting a NULL pointer. This is bound not to work.

However assuming that there is some code missing, this becomes
  1. Sets it's value to NULL:
    monomer* pointforward = NULL;
  2. Construct a monomer class and assign pointforward to point to it:
    pointforward = new monomer(); // Or something similar
  3. Uses it in the constrcution of another monomer class
    monomer* monomeri = new monomer(pointforward, namenum);
  4. And finally deletes it:
    delete pointforward;

This is porbably still an error because you pass the value of pointforward into the constructor for monomeri. I assume that monomeri makes us of this value possibly by storing it in which case at step C when you delete pointforward monomeri is left referencing an object that no longer exists.

when I think about it, the reason I used vectors of pointers is because i couldn't find out how to put my newed objects onto a vector of class objects....
If you have a vector of objects rather than pointer to objects then you don't need to new objects, the allocator of the vector class will handle that for you see these 2 examples

Expand|Select|Wrap|Line Numbers
  1. // Vector of pointers
  2.     vector<monomer*> Nucsp;
  3.  
  4.     monomer* pointforward = new monomer();
  5.  
  6.     monomer* monomeri = new monomer(pointforward, namenum);
  7.  
  8.     //inserting the monomer onto its vector
  9.     nucsp.insert(nucsp.begin(), monomeri);
  10.  
  11. // Compare with
  12.  
  13. // Vector of Objects
  14.  
  15.     vector<monomer> Nucs;
  16.  
  17.     //inserting the monomer onto its vector
  18.     nucs.insert(nucs.begin(), monomer(pointforward, namenum));
  19.  
  20.  
In the second example the nucs vector news the new monomer instance I then provide it with initialisation data. However for that to work properly you may well have to provide a conpy constructor and overload the assigment operator...

Expand|Select|Wrap|Line Numbers
  1. class monomer
  2. {
  3. public:
  4.     monomer(monomer &copy)
  5.     {
  6.         this->data = copy.data;
  7.         // For allocated data remember to allocate and copy
  8.         this->allocatedData = new char[10];
  9.         memcpy(this->allocatedData, copy.allocatedData, 10);
  10.     }
  11.  
  12.     monomer operator=(monomer &copy)
  13.     {
  14.         // Simialr to copy constructor but remember to deallocate memory
  15.         //before reallocating it so as to avoid memory leaks
  16.  
  17.         this->data = copy.data;
  18.         // For allocated data remember to allocate and copy
  19.  
  20.         if ( this->allocatedData != NULL )
  21.         {
  22.             delete[] this->allocatedData;
  23.         }
  24.  
  25.         this->allocatedData = new char[10];
  26.         memcpy(this->allocatedData, copy.allocatedData, 10);
  27.     }
  28. }
  29.  
I hope this provides some insights and leads you onto the next set of questions.
Apr 13 '06 #8

P: 14
I do not know the structure of you class monomer however I infer from how you have used it that contains some (at least 3?) pointers to other instances of itself and that you have a constructor that accepts setup values for these pointers a bit like

Expand|Select|Wrap|Line Numbers
  1. class monomer
  2. {
  3. public:
  4.     monomer *pointforward;
  5.     monomer *pointbackward;
  6.     monomer *pointbranch;
  7.  
  8.     // other members here
  9.  
  10.     monomer(monomer *pforward=NULL, 
  11.                  monomer *pbackward=NULL, 
  12.                  monomer *pbranch=NULL)
  13.     {
  14.         pointforward = pforward;
  15.         pointbackward = pbackward;
  16.         pointbranch = pbranch;
  17.  
  18.        // Initialise other members
  19.     }
  20. }
  21.  
exactly, except that there are three different constructors, one takes one pointer to initialize a monomer with one pointer, one takes two pointers to initialize a monomer with two pointers, and one takes three pointers to initialize a monomer with three pointers. if you look in the posted code, there are four different constructors being used, each of the three mentioned above and the default.

On this basis I have the following questions
  1. You set up 3 monomer * vectors. Can a given instance of the monomer class appear in more than 1 of these vectors?
  2. Each monomer class contains pointers to other instances of the monomer class. Is it possible for 2 separate instances on the monomer class to end up with there internal pointers pointing to the same 3rd instance of the monomer class?
  3. Is it possible for an instance of a monomer class to end up in a vector and being pointed to by another instance of the monomer class.
yes
yes
yes
the third vector is only used at the very end of the program to store the final products. the first two vectors are used throughout, and these have multiple occurances of the same monomer being in both. As there are three different types of monomers with 1, 2, or 3 pointers, the end product is a vector full of pointers to non-complete binary trees of monomers. with only the positions of the most "senior" monomers of each tree (root nodes) being stored in the vectors as pointers. so the monomers with only one pointer are the leaves, the monomers with two pointers are the sections between branch-points, and the monomers with three pointers are the branch-points themselves.


  1. Sets it's value to NULL:
    monomer* pointforward = NULL;
  2. Uses it in the constrcution of another monomer class
    monomer* monomeri = new monomer(pointforward, namenum);
  3. And finally deletes it:
    delete pointforward;

The the code is as it is posted then in step C it is deleting a NULL pointer. This is bound not to work.
i guess the pointforward pointer doesn't need to be deleted, i was just covering my ass. I only initialize it to pass into the constructor so that it knows which constructor to use, (i.e. which type of monomer to make). This is necessary, i think, because I need monomers of different types. Would it be better to used multiple classes, i.e. class monomer1, class monomer2, class monomer3, rather than have three different constructors?? or a series of derived classes.

the program runs most of the time. but when i input big numbers (corresponding to the number of each type of monomer to be initialized) it crashes.

i think there is a memory leak, either upon initialization of the monomers, or somewhere in the vector shuffling.
Apr 13 '06 #9

Banfa
Expert Mod 5K+
P: 8,916
the program runs most of the time. but when i input big numbers (corresponding to the number of each type of monomer to be initialized) it crashes.

i think there is a memory leak, either upon initialization of the monomers, or somewhere in the vector shuffling.
It is unlikely that "memory leaks" are causing the crash unless your system has fairly limited memory, however I assume this code is running on a PC. A memory leak is basically defined as losing track of a piece allocated memory by removing the last reference (pointer) to it so that it can not be freed.

On a lot of modern systems (WIN32) even if you do this the OS remembers that the memory is allocated and automatically deallocates it when the program closes.

The only way a "memory leak" could cause a crash is if all RAM was used up causing a new or malloc to fail and the return of these functions is not checked.

new and malloc can fail for other reasons too so when you new or malloc something you should check what is returned like so

Expand|Select|Wrap|Line Numbers
  1.     monomer *monomeri = new monomer(pointforward, namenum);
  2.  
  3.     if (monomeri != NULL)
  4.     {
  5.         // Pointer good continue processing
  6.     }
  7.     else
  8.     {
  9.         // Pointer bad memory allocation failure handle error
  10.     }
  11.  
The other thing that could be going on is deleting something before it is finished with. If you have new'd something stored the pointer to it and then deleted it the stored pointer will be pointing at nothing and trying to use it could easily cause a crash.

My advice is to add an allocation check to everywhere that you new something even if all you do in the error handling is print a message and exit and to examine all the places you delete an object to make sure that it really is only happening when the objects are no longer in use.
Apr 18 '06 #10

P: 14
thanks for the advice, i've learned that I need to use assert a lot more than i do and that checks built in during coding are a very good idea. thanks for all your help. peace.
Apr 19 '06 #11

Post your reply

Sign in to post your reply or Sign up for a free account.