Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Considerations and implementation of a method to copy the vector<t>::iterator</t>

Considerations and implementation of a method to copy the vector<t>::iterator</t>

Scheduled Pinned Locked Moved C / C++ / MFC
helpgraphicsperformance
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Cyrilix
    wrote on last edited by
    #1

    My title is probably not very well phrased, but here is the problem. Let's say I've got functions a(), b(), where a() calls b(), and b() calls vector<T>::iterator iter = someVector.begin(). b() needs to pass this iterator down to a() via a void* mechanism, without returning it (essentially using reference passing), so more explicitly, the two functions are:

    void a(void*& param);
    void b(void*& param);

    The problem is, we can't simply do something like this:

    vector<T>::iterator iter = someVector.begin();
    param = reinterpret_cast<void*>(iter)

    This is because the compiler (MSVC9) will complain about trying to cast an iterator to a void*:

    error C2440: 'reinterpret_cast' : cannot convert from 'std::_Vector_iterator<_Ty,_Alloc>' to 'void *'

    Likewise, I can't do something like...

    vector<T>::iterator iter = someVector.begin();
    param = reinterpret_cast<void*>(&iter)

    ...because even though this will compile, it will not work because begin() actually returns an iterator object and not a pointer to some memory location, so the memory address of that object will go out of scope (not sure when, but I'm guessing when you leave b()). So, because I can't do any of this, I thought that maybe I could do a memory copy of the iterator, pass it up as a void*, and then cast it back to an iterator, so something along these lines:

    vector<T>::iterator iter = someVector.begin();
    void* mem = malloc(sizeof(vector<T>::iterator));
    //memcpy starting from &iter up to the size, into the malloc memory
    param = mem;

    And on the flip side, in order to decode my data, I'd do something like this:

    vector<T>::iterator = reinterpret_cast<vector<T>::iterator>(param);

    I'm wondering whether or not this idea of mine is feasible or will cause me many problems, or if there is a better way of doing what I'd like to do, given the limitations (can only pass by void* reference). Thanks.

    S M 2 Replies Last reply
    0
    • C Cyrilix

      My title is probably not very well phrased, but here is the problem. Let's say I've got functions a(), b(), where a() calls b(), and b() calls vector<T>::iterator iter = someVector.begin(). b() needs to pass this iterator down to a() via a void* mechanism, without returning it (essentially using reference passing), so more explicitly, the two functions are:

      void a(void*& param);
      void b(void*& param);

      The problem is, we can't simply do something like this:

      vector<T>::iterator iter = someVector.begin();
      param = reinterpret_cast<void*>(iter)

      This is because the compiler (MSVC9) will complain about trying to cast an iterator to a void*:

      error C2440: 'reinterpret_cast' : cannot convert from 'std::_Vector_iterator<_Ty,_Alloc>' to 'void *'

      Likewise, I can't do something like...

      vector<T>::iterator iter = someVector.begin();
      param = reinterpret_cast<void*>(&iter)

      ...because even though this will compile, it will not work because begin() actually returns an iterator object and not a pointer to some memory location, so the memory address of that object will go out of scope (not sure when, but I'm guessing when you leave b()). So, because I can't do any of this, I thought that maybe I could do a memory copy of the iterator, pass it up as a void*, and then cast it back to an iterator, so something along these lines:

      vector<T>::iterator iter = someVector.begin();
      void* mem = malloc(sizeof(vector<T>::iterator));
      //memcpy starting from &iter up to the size, into the malloc memory
      param = mem;

      And on the flip side, in order to decode my data, I'd do something like this:

      vector<T>::iterator = reinterpret_cast<vector<T>::iterator>(param);

      I'm wondering whether or not this idea of mine is feasible or will cause me many problems, or if there is a better way of doing what I'd like to do, given the limitations (can only pass by void* reference). Thanks.

      S Offline
      S Offline
      Stuart Dootson
      wrote on last edited by
      #2

      Apart from the fact you're using malloc, the last idea's OK. Use new instead - it's C++, man!

      param = reinterpret_cast<void*>(new vector<T>::iterator(someVector.begin()));

      Remember to delete it afterwards as well....

      Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

      C 1 Reply Last reply
      0
      • S Stuart Dootson

        Apart from the fact you're using malloc, the last idea's OK. Use new instead - it's C++, man!

        param = reinterpret_cast<void*>(new vector<T>::iterator(someVector.begin()));

        Remember to delete it afterwards as well....

        Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

        C Offline
        C Offline
        Cyrilix
        wrote on last edited by
        #3

        Yeah, well, the way I see it, malloc just does a simple memory allocation, whereas new also calls the parameterless constructor. In this case, since I'm overwriting everything, I figured malloc was the better way, but from my testing, it seems that new works as well. I've managed to get some sample code working, and it seems to be fine when T = int, but I've been told that it may not work where T is a more complicated class.

        S 1 Reply Last reply
        0
        • C Cyrilix

          Yeah, well, the way I see it, malloc just does a simple memory allocation, whereas new also calls the parameterless constructor. In this case, since I'm overwriting everything, I figured malloc was the better way, but from my testing, it seems that new works as well. I've managed to get some sample code working, and it seems to be fine when T = int, but I've been told that it may not work where T is a more complicated class.

          S Offline
          S Offline
          Stuart Dootson
          wrote on last edited by
          #4

          Should be fine, no matter what T is - an iterator generally only holds a reference to an item in a container (for simple, container iterators).

          Cyrilix wrote:

          new also calls the parameterless constructor

          new will call whichever constructor you specify. In my example, I use teh copy constructor.

          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

          1 Reply Last reply
          0
          • C Cyrilix

            My title is probably not very well phrased, but here is the problem. Let's say I've got functions a(), b(), where a() calls b(), and b() calls vector<T>::iterator iter = someVector.begin(). b() needs to pass this iterator down to a() via a void* mechanism, without returning it (essentially using reference passing), so more explicitly, the two functions are:

            void a(void*& param);
            void b(void*& param);

            The problem is, we can't simply do something like this:

            vector<T>::iterator iter = someVector.begin();
            param = reinterpret_cast<void*>(iter)

            This is because the compiler (MSVC9) will complain about trying to cast an iterator to a void*:

            error C2440: 'reinterpret_cast' : cannot convert from 'std::_Vector_iterator<_Ty,_Alloc>' to 'void *'

            Likewise, I can't do something like...

            vector<T>::iterator iter = someVector.begin();
            param = reinterpret_cast<void*>(&iter)

            ...because even though this will compile, it will not work because begin() actually returns an iterator object and not a pointer to some memory location, so the memory address of that object will go out of scope (not sure when, but I'm guessing when you leave b()). So, because I can't do any of this, I thought that maybe I could do a memory copy of the iterator, pass it up as a void*, and then cast it back to an iterator, so something along these lines:

            vector<T>::iterator iter = someVector.begin();
            void* mem = malloc(sizeof(vector<T>::iterator));
            //memcpy starting from &iter up to the size, into the malloc memory
            param = mem;

            And on the flip side, in order to decode my data, I'd do something like this:

            vector<T>::iterator = reinterpret_cast<vector<T>::iterator>(param);

            I'm wondering whether or not this idea of mine is feasible or will cause me many problems, or if there is a better way of doing what I'd like to do, given the limitations (can only pass by void* reference). Thanks.

            M Offline
            M Offline
            Michael Dunn
            wrote on last edited by
            #5

            In any recent version of VC, iterators are not simple pointers. There is some debug info kept around to detect dangling iterators and iterators that point outside of their containers. So doing a straight memcpy will work only as long as the original iterator exists. What about this:

            vector::iterator* piter = new vector::iterator ( someVector.begin() );
            void* pv = (void*) piter;

            ?


            Last modified: 5hrs 10mins after originally posted -- fixde tpyo

            --Mike--

            C 1 Reply Last reply
            0
            • M Michael Dunn

              In any recent version of VC, iterators are not simple pointers. There is some debug info kept around to detect dangling iterators and iterators that point outside of their containers. So doing a straight memcpy will work only as long as the original iterator exists. What about this:

              vector::iterator* piter = new vector::iterator ( someVector.begin() );
              void* pv = (void*) piter;

              ?


              Last modified: 5hrs 10mins after originally posted -- fixde tpyo

              --Mike--

              C Offline
              C Offline
              Cyrilix
              wrote on last edited by
              #6

              I'll try this, thanks.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups