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. Vector elements and the heap...or the stack...

Vector elements and the heap...or the stack...

Scheduled Pinned Locked Moved C / C++ / MFC
data-structureshelpgraphicsalgorithmsannouncement
5 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.
  • M Offline
    M Offline
    Mike the Red
    wrote on last edited by
    #1

    I have a BYTE array that I'm trying to split into parts and put the parts in a vector:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <malloc.h> // For the 'on the stack' version
    #ifndef LPBYTE
    typedef unsigned char * LPBYTE // For you OS X types ; )
    #endif

    void split(vector<LPBYTE>& vect, const LPBYTE& lpbData) {
    LPBYTE start = lpbData; // first part starts at beginning of lpbData
    LPBYTE end = lpbData + (size_t) 2; // This is normally calculated by finding a separating sequence within lpbData
    size_t len = distance(start, end); // Size of the part

    // Add part to vector
    LPBYTE lpbPart = new BYTE\[len\];
    /\* Or, on the stack 
    LPBYTE lpbPart = (LPBYTE) \_alloca(len)
    \*/
    
    memcpy(lpbPart, start, len);
    vect.push\_back( lpbPart );
    

    }
    int main() {
    LPBYTE data = {'a', 'b', 'c', 12, 22, 'Q'};
    vector<LPBYTE> parts;
    split(parts, data);

    for (vector<LPBYTE>::iterator vIT = parts.begin(); vIT != parts.end(); vIT++)
    	cout << (char \*) \*vIT << "\\n";
    parts.clear(); // This does no good, but I threw it in for good measure o\_O
    

    }

    The problem with the heap version is that it leaks. But if I use the stack version, or if I were to delete lpbPart inside split() (after adding it to the vector), a bunch of garbage is output 'cause the address is no longer valid. I could iterate through the vector when I'm done with it, delete-ing each element... but I was told recently that that is a bad programming practice. I am leaning towards deriving a class from vector and delete-ing the elements in the destructor, but I thought I'd run it by you guys first and see if there was a better way. OR if there is a way to make a sub-array of an array, where the sub-array points to an address within the array but has a length shorter than the distance from the address within the source array to its end. This way would avoid the stack and the heap and the addresses would be valid so long as the source LPBYTE data was valid. It isn't good code, but to better explain what I mean:

    LPBYTE data = {'a', 'b', 'c', 12, 22, 'Q'};
    BYTE sub[2];
    &sub = data + 2; // This is bad code, but what I mean is to point sub at the 'c' in data

    As always, any help ya'll can give is greatly appreciated! MZR

    _ S 2 Replies Last reply
    0
    • M Mike the Red

      I have a BYTE array that I'm trying to split into parts and put the parts in a vector:

      #include <iostream>
      #include <vector>
      #include <algorithm>
      #include <malloc.h> // For the 'on the stack' version
      #ifndef LPBYTE
      typedef unsigned char * LPBYTE // For you OS X types ; )
      #endif

      void split(vector<LPBYTE>& vect, const LPBYTE& lpbData) {
      LPBYTE start = lpbData; // first part starts at beginning of lpbData
      LPBYTE end = lpbData + (size_t) 2; // This is normally calculated by finding a separating sequence within lpbData
      size_t len = distance(start, end); // Size of the part

      // Add part to vector
      LPBYTE lpbPart = new BYTE\[len\];
      /\* Or, on the stack 
      LPBYTE lpbPart = (LPBYTE) \_alloca(len)
      \*/
      
      memcpy(lpbPart, start, len);
      vect.push\_back( lpbPart );
      

      }
      int main() {
      LPBYTE data = {'a', 'b', 'c', 12, 22, 'Q'};
      vector<LPBYTE> parts;
      split(parts, data);

      for (vector<LPBYTE>::iterator vIT = parts.begin(); vIT != parts.end(); vIT++)
      	cout << (char \*) \*vIT << "\\n";
      parts.clear(); // This does no good, but I threw it in for good measure o\_O
      

      }

      The problem with the heap version is that it leaks. But if I use the stack version, or if I were to delete lpbPart inside split() (after adding it to the vector), a bunch of garbage is output 'cause the address is no longer valid. I could iterate through the vector when I'm done with it, delete-ing each element... but I was told recently that that is a bad programming practice. I am leaning towards deriving a class from vector and delete-ing the elements in the destructor, but I thought I'd run it by you guys first and see if there was a better way. OR if there is a way to make a sub-array of an array, where the sub-array points to an address within the array but has a length shorter than the distance from the address within the source array to its end. This way would avoid the stack and the heap and the addresses would be valid so long as the source LPBYTE data was valid. It isn't good code, but to better explain what I mean:

      LPBYTE data = {'a', 'b', 'c', 12, 22, 'Q'};
      BYTE sub[2];
      &sub = data + 2; // This is bad code, but what I mean is to point sub at the 'c' in data

      As always, any help ya'll can give is greatly appreciated! MZR

      _ Offline
      _ Offline
      _Superman_
      wrote on last edited by
      #2

      If you have used new[], you have to use delete[]. That is not bad programming practice. Rather, I would say that using new[] in the first place is bad programming practice. Are you trying to create several smaller BYTE arrays from one large BYTE array? If so, I would recommend creating a vector> sub. You could then assign values to sub as follows.

      vector small;

      small.assign(data.begin(), data.begin() + 2);
      sub.push_back(small);

      small.assign(data.begin() + 3, data.begin() + 5);
      sub.push_back(small);

      Or you can use Boost.MultiArray[^].

      «_Superman_» I love work. It gives me something to do between weekends.

      1 Reply Last reply
      0
      • M Mike the Red

        I have a BYTE array that I'm trying to split into parts and put the parts in a vector:

        #include <iostream>
        #include <vector>
        #include <algorithm>
        #include <malloc.h> // For the 'on the stack' version
        #ifndef LPBYTE
        typedef unsigned char * LPBYTE // For you OS X types ; )
        #endif

        void split(vector<LPBYTE>& vect, const LPBYTE& lpbData) {
        LPBYTE start = lpbData; // first part starts at beginning of lpbData
        LPBYTE end = lpbData + (size_t) 2; // This is normally calculated by finding a separating sequence within lpbData
        size_t len = distance(start, end); // Size of the part

        // Add part to vector
        LPBYTE lpbPart = new BYTE\[len\];
        /\* Or, on the stack 
        LPBYTE lpbPart = (LPBYTE) \_alloca(len)
        \*/
        
        memcpy(lpbPart, start, len);
        vect.push\_back( lpbPart );
        

        }
        int main() {
        LPBYTE data = {'a', 'b', 'c', 12, 22, 'Q'};
        vector<LPBYTE> parts;
        split(parts, data);

        for (vector<LPBYTE>::iterator vIT = parts.begin(); vIT != parts.end(); vIT++)
        	cout << (char \*) \*vIT << "\\n";
        parts.clear(); // This does no good, but I threw it in for good measure o\_O
        

        }

        The problem with the heap version is that it leaks. But if I use the stack version, or if I were to delete lpbPart inside split() (after adding it to the vector), a bunch of garbage is output 'cause the address is no longer valid. I could iterate through the vector when I'm done with it, delete-ing each element... but I was told recently that that is a bad programming practice. I am leaning towards deriving a class from vector and delete-ing the elements in the destructor, but I thought I'd run it by you guys first and see if there was a better way. OR if there is a way to make a sub-array of an array, where the sub-array points to an address within the array but has a length shorter than the distance from the address within the source array to its end. This way would avoid the stack and the heap and the addresses would be valid so long as the source LPBYTE data was valid. It isn't good code, but to better explain what I mean:

        LPBYTE data = {'a', 'b', 'c', 12, 22, 'Q'};
        BYTE sub[2];
        &sub = data + 2; // This is bad code, but what I mean is to point sub at the 'c' in data

        As always, any help ya'll can give is greatly appreciated! MZR

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

        Mike the Red wrote:

        OR if there is a way to make a sub-array of an array, where the sub-array points to an address within the array but has a length shorter than the distance from the address within the source array to its end. This way would avoid the stack and the heap and the addresses would be valid so long as the source LPBYTE data was valid. It isn't good code, but to better explain what I mean:

        Arrays==pointers. The size of an array is not (repeat NOT) stored with the pointer. So, you could store pointers into the original array in the vector, but you'd need to store some way of knowing what the end ot the part was. You could do it like this:

        void split(vector<std::pair<LPBYTE, LPBYTE> >& vect, const LPBYTE& lpbData)
        {
        LPBYTE start = lpbData; // first part starts at beginning of lpbData
        LPBYTE end = lpbData + (size_t) 2; // This is normally calculated by finding a separating sequence within lpbData
        vect.push_back(std::make_pair(start, end));
        }

        and you'd have to declare parts as

        vector<std::pair<LPBYTE, LPBYTE> > parts;

        This concept is known as an iterator range and is supported within some[^] libraries[^]. The iterator range is what is known as a half-open range. What this means is that the start of the range is part of the range, but the end of the range actually points to the first element AFTER the range. Sounds odd? Well, it's the way that all the STL iterators and algorithms work, so these ranges have compatibility with those, which is a good thing, IMO. HTH!

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

        M 1 Reply Last reply
        0
        • S Stuart Dootson

          Mike the Red wrote:

          OR if there is a way to make a sub-array of an array, where the sub-array points to an address within the array but has a length shorter than the distance from the address within the source array to its end. This way would avoid the stack and the heap and the addresses would be valid so long as the source LPBYTE data was valid. It isn't good code, but to better explain what I mean:

          Arrays==pointers. The size of an array is not (repeat NOT) stored with the pointer. So, you could store pointers into the original array in the vector, but you'd need to store some way of knowing what the end ot the part was. You could do it like this:

          void split(vector<std::pair<LPBYTE, LPBYTE> >& vect, const LPBYTE& lpbData)
          {
          LPBYTE start = lpbData; // first part starts at beginning of lpbData
          LPBYTE end = lpbData + (size_t) 2; // This is normally calculated by finding a separating sequence within lpbData
          vect.push_back(std::make_pair(start, end));
          }

          and you'd have to declare parts as

          vector<std::pair<LPBYTE, LPBYTE> > parts;

          This concept is known as an iterator range and is supported within some[^] libraries[^]. The iterator range is what is known as a half-open range. What this means is that the start of the range is part of the range, but the end of the range actually points to the first element AFTER the range. Sounds odd? Well, it's the way that all the STL iterators and algorithms work, so these ranges have compatibility with those, which is a good thing, IMO. HTH!

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

          M Offline
          M Offline
          Mike the Red
          wrote on last edited by
          #4

          That's exactly what I was looking for - thank you! I know you've mentioned BOOST to me a couple times, and I may look into it when I've learned a bit more, but if I use other people's code/libraries, how will I learn for myself? MZR

          S 1 Reply Last reply
          0
          • M Mike the Red

            That's exactly what I was looking for - thank you! I know you've mentioned BOOST to me a couple times, and I may look into it when I've learned a bit more, but if I use other people's code/libraries, how will I learn for myself? MZR

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

            Mike the Red wrote:

            I may look into it when I've learned a bit more, but if I use other people's code/libraries, how will I learn for myself?

            Quite correct - but at the same time, you can't implement EVERYTHING yourself (you're using a compiler you haven't written yourself, I presume :)). It's most important to learn concepts, how they work, and when to apply them. Implementation? Not always so important.

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

            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