splitting a vector into two parts

Discussion in 'C++' started by AG, Jan 18, 2007.

  1. AG

    AG Guest

    Hi,

    I have a vector that represent memory in my code. I would like to split it into two smaller vector, without
    copying it. I want the split to be "in-place", so that modifications on the two smaller vectors would affect the
    original one.

    Exemple :

    int N=10;
    int i;
    vector<int> a = vector<int>(N,0);
    for(i=0;i<N;i++)
    a.push_back(i);

    vector<int>::iterator mid = a.begin();
    mid+=5;

    vector<int> & a1 = vector<int>(a.begin(),mid); // something like this
    vector<int> & a2 = vector<int>(mid,a.end()); // something like this

    a1[0] = 10;
    a2[0] = 22;

    cout << "a ";
    for(mid=a.begin();mid!=a.end();mid++)
    cout << *mid << " ";
    cout << "\na1 ";
    for(mid=a1.begin();mid!=a1.end();mid++)
    cout << *mid << " ";
    cout << "\na2 ";
    for(mid=a2.begin();mid!=a2.end();mid++)
    cout << *mid << " ";

    Would someone know a way to do this ?

    many thanks in advance,

    Alexandre.
    AG, Jan 18, 2007
    #1
    1. Advertising

  2. On Jan 18, 9:50 am, "AG" <> wrote:
    > Hi,
    >
    > I have a vector that represent memory in my code. I would like to split it into two smaller vector, without
    > copying it. I want the split to be "in-place", so that modifications on the two smaller vectors would affect the
    > original one.


    You can't do that with a vector, each vector handles the objects it
    contains. What if (in your example) someone were to do something like:

    a1[0] = 5;
    a[0] = 1;

    Then, suddenly, a1[0] == 1, which is not logical in any way, since you
    have not changed a1.

    What you could do is to either use normal arrays:

    int* a = new int[10];
    int* a1 = a;
    int* a2 = a[5];

    Just make sure that you don't delete a before you are done with a1 and
    a2, and don't delete either a1 or a2 (deleting a1 is the same as
    deleting a, and deleting a2 will probably throw an exception at the
    very least).

    Or you can make a wrapper-class that works much like a vector and takes
    two random-access iterators as constructors (start and end iterators).

    By the way, if it's to represent memory you might want to use char
    instead of int, since that allows your to access each byte
    individually.

    --
    Erik Wikström
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Jan 18, 2007
    #2
    1. Advertising

  3. AG

    AG Guest

    >You can't do that with a vector, each vector handles the objects it
    >contains. What if (in your example) someone were to do something
    >like:
    >
    >a1[0] = 5;
    >a[0] = 1;
    >
    >Then, suddenly, a1[0] == 1, which is not logical in any way, since
    >you
    >have not changed a1.


    This is exactly the behavior I would expect, and that is also what you
    get when doing :

    int a = 5;
    int &b = a;

    b = 1;

    Then, suddenly, a == 1, which IS logical.



    >What you could do is to either use normal arrays:


    >int* a = new int[10];
    >int* a1 = a;
    >int* a2 = a[5];


    That's what I was used to do, but moving to vectors... I would have
    expected the same behavior possible. So bad.
    AG, Jan 18, 2007
    #3
  4. AG

    Ondra Holub Guest

    AG napsal:
    > Hi,
    >
    > I have a vector that represent memory in my code. I would like to split it into two smaller vector, without
    > copying it. I want the split to be "in-place", so that modifications on the two smaller vectors would affect the
    > original one.
    >
    > Exemple :
    >
    > int N=10;
    > int i;
    > vector<int> a = vector<int>(N,0);
    > for(i=0;i<N;i++)
    > a.push_back(i);
    >
    > vector<int>::iterator mid = a.begin();
    > mid+=5;
    >
    > vector<int> & a1 = vector<int>(a.begin(),mid); // something like this
    > vector<int> & a2 = vector<int>(mid,a.end()); // something like this
    >
    > a1[0] = 10;
    > a2[0] = 22;
    >
    > cout << "a ";
    > for(mid=a.begin();mid!=a.end();mid++)
    > cout << *mid << " ";
    > cout << "\na1 ";
    > for(mid=a1.begin();mid!=a1.end();mid++)
    > cout << *mid << " ";
    > cout << "\na2 ";
    > for(mid=a2.begin();mid!=a2.end();mid++)
    > cout << *mid << " ";
    >
    > Would someone know a way to do this ?
    >
    > many thanks in advance,
    >
    > Alexandre.


    Write your own class, which stores reference to original vector and
    indexes of begin and end for your subvector (you cannot store
    iterators, because iterators may become invalid when size of vector is
    increased).
    Ondra Holub, Jan 18, 2007
    #4
  5. AG

    AG Guest

    What about using val_array/slice_array ?
    AG, Jan 18, 2007
    #5
  6. On Jan 18, 3:55 pm, "AG" <> wrote:
    > What about using val_array/slice_array ?


    You could use a valarray and slice it up yes. It does, however, not
    dynamically grow as a vector would (and I assume that's why you use a
    vector instead of a normal array), but it can be resized. Don't know
    how slices work when resizing tough.

    --
    Erik Wikström
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Jan 18, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy Fish
    Replies:
    4
    Views:
    363
    Jon A. Cruz
    Aug 24, 2003
  2. John Ericson
    Replies:
    0
    Views:
    419
    John Ericson
    Jul 19, 2003
  3. Fabian Steiner

    Splitting device addresses into parts

    Fabian Steiner, Sep 26, 2006, in forum: Python
    Replies:
    9
    Views:
    262
    Lawrence D'Oliveiro
    Sep 27, 2006
  4. Replies:
    8
    Views:
    1,890
    Csaba
    Feb 18, 2006
  5. Tore Aursand

    Splitting an array into "even" parts

    Tore Aursand, Nov 5, 2003, in forum: Perl Misc
    Replies:
    5
    Views:
    186
    Tore Aursand
    Nov 5, 2003
Loading...

Share This Page