problem to fill a combination of containers 
Author Message
 problem to fill a combination of containers

Dear All

I have a problem to insert elements in a combination of containers.
Here is the declaration of the container I would like to use:
vector< set<myElement> > myContainer(vectorSize,set<myElement>());
The size of the vector is known but not yet the sizes of the different
sets.
Within a for loop, I build some myElements and try to insert them in
the correct set with:
myContainer[num].insert(myElement);
num is strictly less than vectorSize
myElement is defined as a struct of 2 int and overloads the operator<
in order to do the insertion
With a vectorSize equals to 1, the first insertion is done OK but it
fails within the second insertion; with a vectorSize>1 sometimes even
the first insertion fails.

What I don't understand is that I've done something similar that works
with a vector of vector of int and using a push_back instead of the
insert.

Thanks for your help.

Hlne.



Mon, 12 Dec 2005 18:34:49 GMT  
 problem to fill a combination of containers

Quote:

>Dear All

>I have a problem to insert elements in a combination of containers.
>Here is the declaration of the container I would like to use:
>vector< set<myElement> > myContainer(vectorSize,set<myElement>());
>The size of the vector is known but not yet the sizes of the different
>sets.
>Within a for loop, I build some myElements and try to insert them in
>the correct set with:
>myContainer[num].insert(myElement);
>num is strictly less than vectorSize
>myElement is defined as a struct of 2 int and overloads the operator<
>in order to do the insertion

Your overloaded operator< is probably incorrect - it is undefined
behaviour to implement one that doesn't produce a strict weak
ordering.

Quote:
>With a vectorSize equals to 1, the first insertion is done OK but it
>fails within the second insertion; with a vectorSize>1 sometimes even
>the first insertion fails.

>What I don't understand is that I've done something similar that works
>with a vector of vector of int and using a push_back instead of the
>insert.

If you're comparing two int elements, make sure you do a
"lexicographic" style compare. e.g. something like

return a.first < b.first? true:
        b.first < a.first? false:
         a.second < b.second;

Tom



Mon, 12 Dec 2005 18:57:22 GMT  
 problem to fill a combination of containers


Quote:
> Dear All

> I have a problem to insert elements in a combination of containers.
> Here is the declaration of the container I would like to use:
> vector< set<myElement> > myContainer(vectorSize,set<myElement>());
> The size of the vector is known but not yet the sizes of the different
> sets.
> Within a for loop, I build some myElements and try to insert them in
> the correct set with:
> myContainer[num].insert(myElement);
> num is strictly less than vectorSize
> myElement is defined as a struct of 2 int and overloads the operator<
> in order to do the insertion
> With a vectorSize equals to 1, the first insertion is done OK but it

so you can assert(num == 0); !!! can you?:)

Quote:
> fails within the second insertion; with a vectorSize>1 sometimes even
> the first insertion fails.

> What I don't understand is that I've done something similar that works
> with a vector of vector of int and using a push_back instead of the
> insert.

> Thanks for your help.

> Hlne.

also probably the operator < is not correct .
it should be like this:
 bool operator <(const myElement& a) const
{
    if (x1 < a.x1) retrun true;
    if (x1 > a.x1) retrun false;
    if (x2 < a.x2) retrun true;
    if (x2 > a.x2) retrun false;
      ..............other members.................
    return false;
Quote:
}



Mon, 12 Dec 2005 19:01:19 GMT  
 problem to fill a combination of containers

Quote:



> > Dear All

> > I have a problem to insert elements in a combination of containers.
> > Here is the declaration of the container I would like to use:
> > vector< set<myElement> > myContainer(vectorSize,set<myElement>());
> > The size of the vector is known but not yet the sizes of the different
> > sets.
> > Within a for loop, I build some myElements and try to insert them in
> > the correct set with:
> > myContainer[num].insert(myElement);
> > num is strictly less than vectorSize
> > myElement is defined as a struct of 2 int and overloads the operator<
> > in order to do the insertion
> > With a vectorSize equals to 1, the first insertion is done OK but it

> so you can assert(num == 0); !!! can you?:)

num is actually computed from other data and before using it in the
insert instruction, I've printed it out and yes, it is equal to 0, at
least on my screen... How do you think it could be something else?

- Show quoted text -

Quote:
> > fails within the second insertion; with a vectorSize>1 sometimes even
> > the first insertion fails.

> > What I don't understand is that I've done something similar that works
> > with a vector of vector of int and using a push_back instead of the
> > insert.

> > Thanks for your help.

> > Hlne.

> also probably the operator < is not correct .
> it should be like this:
>  bool operator <(const myElement& a) const
> {
>     if (x1 < a.x1) retrun true;
>     if (x1 > a.x1) retrun false;
>     if (x2 < a.x2) retrun true;
>     if (x2 > a.x2) retrun false;
>       ..............other members.................
>     return false;
> }

Actually myElement is even simpler and I am doing a usual less than
comparison on the second int only. Here is exactly how myElement looks
like.
struct myElement {
  int x1;
  int x2;
public:
  bool operator<(const myElement & myElt) const {
    return (x2 < myElt.x2);
  }

Quote:
};

Any more idea?
Thanks for your help.

Hlne.



Mon, 12 Dec 2005 22:13:24 GMT  
 problem to fill a combination of containers

Quote:
> I have a problem to insert elements in a combination of containers.
> Here is the declaration of the container I would like to use:
> vector< set<myElement> > myContainer(vectorSize,set<myElement>());
> The size of the vector is known but not yet the sizes of the different
> sets.
> Within a for loop, I build some myElements and try to insert them in
> the correct set with:
> myContainer[num].insert(myElement);
> num is strictly less than vectorSize
> myElement is defined as a struct of 2 int and overloads the operator<
> in order to do the insertion
> With a vectorSize equals to 1, the first insertion is done OK but it
> fails within the second insertion; with a vectorSize>1 sometimes even
> the first insertion fails.

What exactly does "fail" mean here? It crashes? The element does not get
inserted? Something else?

Note that, the way myElement::operator< is defined, two elements with
equal x2 members are considered equal and the set won't store a second
copy.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Mon, 12 Dec 2005 22:30:36 GMT  
 problem to fill a combination of containers

Quote:

> Actually myElement is even simpler and I am doing a usual less than
> comparison on the second int only. Here is exactly how myElement looks
> like.
> struct myElement {
>   int x1;
>   int x2;
> public:
>   bool operator<(const myElement & myElt) const {
>     return (x2 < myElt.x2);
>   }
> };

then, as others pointed it out already, please note that the insertion
(1, x20)
(3, x20)
(45, x20)
will result of only one element in the map (the last one).

otherwise send us a piece of code to understand more clearly what's the
problem with your map:)



Mon, 12 Dec 2005 23:05:50 GMT  
 problem to fill a combination of containers

Quote:



> > I have a problem to insert elements in a combination of containers.
> > Here is the declaration of the container I would like to use:
> > vector< set<myElement> > myContainer(vectorSize,set<myElement>());
> > The size of the vector is known but not yet the sizes of the different
> > sets.
> > Within a for loop, I build some myElements and try to insert them in
> > the correct set with:
> > myContainer[num].insert(myElement);
> > num is strictly less than vectorSize
> > myElement is defined as a struct of 2 int and overloads the operator<
> > in order to do the insertion
> > With a vectorSize equals to 1, the first insertion is done OK but it
> > fails within the second insertion; with a vectorSize>1 sometimes even
> > the first insertion fails.

> What exactly does "fail" mean here? It crashes? The element does not get
> inserted? Something else?

It means the program crashes on this insertion instruction with a
'cannot read memory' message.

Quote:

> Note that, the way myElement::operator< is defined, two elements with
> equal x2 members are considered equal and the set won't store a second
> copy.

I am OK with that.


Tue, 13 Dec 2005 01:00:50 GMT  
 problem to fill a combination of containers


Quote:
> > What exactly does "fail" mean here? It crashes? The element does not
get
> > inserted? Something else?

> It means the program crashes on this insertion instruction with a
> 'cannot read memory' message.

Show some code that reproduces the problem. If num is indeed within
bounds, I don't see any reason for a crash.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Tue, 13 Dec 2005 01:04:27 GMT  
 problem to fill a combination of containers

Quote:





> > > What exactly does "fail" mean here? It crashes? The element does not
>  get
> > > inserted? Something else?

> > It means the program crashes on this insertion instruction with a
> > 'cannot read memory' message.

> Show some code that reproduces the problem. If num is indeed within
> bounds, I don't see any reason for a crash.

Here is my actual code. I hope everything relevant is here. Otherwise
do not hesitate to ask me for more details.

  vector< set<sequencedTime> >
sequencedTimes(runwayNum,set<sequencedTime>());
  int * times = new int[indivSize];
  for(int i=0; i<indivSize; i++) {
    int earliest = (_ptrFleet->GetAircraftWithIndex(i))->GetEarliestTime();
    int latest = (_ptrFleet->GetAircraftWithIndex(i))->GetLatestTime();
    int time = earliest + (indiv->_proportions)[i] *
(latest-earliest);
    times[i] = time;
    sequencedTime seqTime = {i+1,time};
    int runwayLabel = (indiv->_runways)[i];
    pair<set<sequencedTime>::iterator,bool> result =
(sequencedTimes[runwayLabel-1]).insert(seqTime);
  }

'runwayNum' is equal to 1
'indivSize' is equal to 10
They are arguments given to the program.
'earliest' and 'latest' are also data input to the program.
The arrays '_runways' and '_proportions' are of size 10 ('indivSize')
and contain the following values before entering the 'for' loop.
 [runways] 1 1 1 1 1 1 1 1 1 1
 [(aircraft)/proportion] (1)/0.074 (2)/0.000 (3)/0.057 (4)/0.033
(5)/0.031 (6)/0
.075 (7)/0.033 (8)/0.086 (9)/0.079 (10)/0.051
In the last execution, the first 'seqTime' is {1,160} and is inserted
ok and the second is {2,195} and makes the program crashes.

The 'sequencedTime' element is entirely defined as following:
struct sequencedTime {
  int plane;
  int time;
public:
  bool operator<(const sequencedTime & st) const {
    return (time <= st.time);
  }

Quote:
};

Using '<' or '<=' does not make a difference in the program's
behavior. That is it crashes at the second insertion with a 'cannot
read the memory' message.

I've done something pretty similar earlier in my program that works
with a vector of vector of int. Here is the code for this case:

    vector< vector<int> > tmpSequences(runwayNum,vector<int>());
    int * runways = new int[indivSize];
    for(int i=0;i<indivSize;i++) {
        int planeLabel = tmpSeq[i];
        int runwayLabel = (rand()%runwayNum)+1;
        runways[planeLabel-1] = runwayLabel;
        tmpSequences[runwayLabel-1].push_back(planeLabel);
    }

Again 'runwayNum' is equal to 1 and 'indivSize' to 10 and 'tmpSeq' is
an array of length 10 ('indivSize') that can be such as 3 4 5 1 7 9 6
2 10 8

Thanks to all of you for your help.

Hlne.



Tue, 13 Dec 2005 17:36:59 GMT  
 problem to fill a combination of containers
This program compiles, runs and prints expected output:

#pragma warning (disable: 4786)
#include <vector>
#include <set>
#include <iostream>
#include <stdlib.h>
using namespace std;

struct sequencedTime {
    int plane;
    int time;
public:
    bool operator<(const sequencedTime & st) const {
        return (time < st.time);
    }

Quote:
};

int main()
{
    const int runwayNum = 1;
    const int indivSize = 10;
    int _runways[indivSize];
    {
        for (int i = 0; i < indivSize; ++i)
        {
            _runways[i] = 1;
        }
    }

    vector< set<sequencedTime> >
        sequencedTimes(runwayNum,set<sequencedTime>());
    int * times = new int[indivSize];
    for(int i=0; i<indivSize; i++)
    {
        int time = rand();
        times[i] = time;
        sequencedTime seqTime = {i+1,time};
        int runwayLabel = _runways[i];
        pair<set<sequencedTime>::iterator,bool> result =
            (sequencedTimes[runwayLabel-1]).insert(seqTime);
    }
    delete[] times;

    {
        for (int i = 0; i < sequencedTimes.size(); ++i)
        {
            cout << "Set " << i << endl;
            set<sequencedTime>& s = sequencedTimes[i];
            for (set<sequencedTime>::iterator it = s.begin(); it !=
s.end(); ++it)
            {
                cout << "(" << it->plane << "," << it->time << ")" <<
endl;
            }
        }
    }

    return 0;

Quote:
}

I believe it is an accurate enough representation of your logic. Look
for your problem elsewhere. I suspect you have a heap corruption
somewhere before this code executes, which just happens to manifest
itself here.

Oh, and you cannot use <= in your operator<() - it is not a strict weak
ordering. One of the requirements on the predicate is that for any a and
b, if (a < b) then !(b < a), but this will be violated if you use <= and
happen to have equal times.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Quote:




> > > > What exactly does "fail" mean here? It crashes? The element does
not
> >  get
> > > > inserted? Something else?

> > > It means the program crashes on this insertion instruction with a
> > > 'cannot read memory' message.

> > Show some code that reproduces the problem. If num is indeed within
> > bounds, I don't see any reason for a crash.

> Here is my actual code. I hope everything relevant is here. Otherwise
> do not hesitate to ask me for more details.

>   vector< set<sequencedTime> >
> sequencedTimes(runwayNum,set<sequencedTime>());
>   int * times = new int[indivSize];
>   for(int i=0; i<indivSize; i++) {
>     int earliest =

(_ptrFleet->GetAircraftWithIndex(i))->GetEarliestTime();
Quote:
>     int latest =

(_ptrFleet->GetAircraftWithIndex(i))->GetLatestTime();

- Show quoted text -

Quote:
>     int time = earliest + (indiv->_proportions)[i] *
> (latest-earliest);
>     times[i] = time;
>     sequencedTime seqTime = {i+1,time};
>     int runwayLabel = (indiv->_runways)[i];
>     pair<set<sequencedTime>::iterator,bool> result =
> (sequencedTimes[runwayLabel-1]).insert(seqTime);
>   }

> 'runwayNum' is equal to 1
> 'indivSize' is equal to 10
> They are arguments given to the program.
> 'earliest' and 'latest' are also data input to the program.
> The arrays '_runways' and '_proportions' are of size 10 ('indivSize')
> and contain the following values before entering the 'for' loop.
>  [runways] 1 1 1 1 1 1 1 1 1 1
>  [(aircraft)/proportion] (1)/0.074 (2)/0.000 (3)/0.057 (4)/0.033
> (5)/0.031 (6)/0
> .075 (7)/0.033 (8)/0.086 (9)/0.079 (10)/0.051
> In the last execution, the first 'seqTime' is {1,160} and is inserted
> ok and the second is {2,195} and makes the program crashes.

> The 'sequencedTime' element is entirely defined as following:
> struct sequencedTime {
>   int plane;
>   int time;
> public:
>   bool operator<(const sequencedTime & st) const {
>     return (time <= st.time);
>   }
> };
> Using '<' or '<=' does not make a difference in the program's
> behavior. That is it crashes at the second insertion with a 'cannot
> read the memory' message.

> I've done something pretty similar earlier in my program that works
> with a vector of vector of int. Here is the code for this case:

>     vector< vector<int> > tmpSequences(runwayNum,vector<int>());
>     int * runways = new int[indivSize];
>     for(int i=0;i<indivSize;i++) {
> int planeLabel = tmpSeq[i];
> int runwayLabel = (rand()%runwayNum)+1;
> runways[planeLabel-1] = runwayLabel;
> tmpSequences[runwayLabel-1].push_back(planeLabel);
>     }

> Again 'runwayNum' is equal to 1 and 'indivSize' to 10 and 'tmpSeq' is
> an array of length 10 ('indivSize') that can be such as 3 4 5 1 7 9 6
> 2 10 8

> Thanks to all of you for your help.

> Hlne.



Tue, 13 Dec 2005 22:56:17 GMT  
 problem to fill a combination of containers

Quote:

>Here is my actual code. I hope everything relevant is here. Otherwise
>do not hesitate to ask me for more details.

>  vector< set<sequencedTime> >
>sequencedTimes(runwayNum,set<sequencedTime>());
>  int * times = new int[indivSize];

Why int*? Why not:

vector<int> times(indivSize);
??

Quote:

>The 'sequencedTime' element is entirely defined as following:
>struct sequencedTime {
>  int plane;
>  int time;
>public:
>  bool operator<(const sequencedTime & st) const {
>    return (time <= st.time);
>  }
>};
>Using '<' or '<=' does not make a difference in the program's
>behavior. That is it crashes at the second insertion with a 'cannot
>read the memory' message.

Still, <= is always wrong for a strict weak ordering (and will cause a
crash eventually, even if it isn't currently responsible), so use <.

As general advice, if you use containers where possible that reduces
one common area for silly bugs (memory management). Bounds overwriting
is another common problem, so you might want to add an assert to your
vector operator[] implementation to do bounds checking, or switch your
accesses to .at(pos) calls.

Anyway, the bug is elsewhere in your code - the bit you posted is
fine. You are probably corrupting the heap in some earlier code.

Tom



Wed, 14 Dec 2005 01:39:02 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. "illegal pointer combination" problem

2. Problem with serial comm in combination with DLL

3. Allocation problem using EXE and DLL in combination

4. Having a container vested in another container

5. OLE Server Container fast switching of document and container crashes

6. Newbie - sqlDataAdapter->Fill problem

7. Dataadapter.Fill problems

8. OleDbAdapter.Fill Problem

9. Performance problem in autoamtically filling a table using VC++ 5.0

10. Problem Getting VC++ V5.0 Subscriptions Filled

11. Problems with filling a ListCtrl

12. Problem filling CRichEditView with text

 

 
Powered by phpBB® Forum Software