arraysdynamicstdvectorallocationstddeque

Do I need to delete/free dynamically allocated data (e.g. bytearray or std::vector) within a std::deque before I can call pop_back?


As far as I understand push_back() of std::deque copies the data I put in. So, when I put in reference to dynamic data (such as to a dynamic bytearray or std::vector) it copies only the reference to it. Now I try to understand if I have to delete/free my dynamically allocated data before pop_back() from std::deque? C++11 is given. Hope someone can help me out! Below I have my two scenarios in as code examples:

Scenario I:


  typedef struct mystruct{
    uint8_t* data; 
    //other fields may be here
  } mystruct_t;

  mystruct_t my;
  my.data = new uint8_t[3];
  my.data[0] = 'A';
  my.data[1] = 'B';
  my.data[2] = 'C';
  std::deque<mystruct_t> d;
  d.push_back(my);
  // ...
  // Need to delete/free data here, before d.pop_back()?
  d.pop_back();

Scenario II:


  typedef struct mystruct{
    std::vector<uint8_t> data;
    // other fields may be here
  } mystruct_t;

  mystruct_t my;
  my.data.push_back('A');
  my.data.push_back('B');
  my.data.push_back('C');

  std::deque<mystruct_t> d;
  d.push_back(my);
  // ...
  // Need to delete/free data here, before d.pop_back()?
  d.pop_back();


Solution

  • OK, because no one was answering, I try to answer myself considering new findings:

    I made some runtime tests of the code shown above in an endless loop while putting 1 MB of data in the bytearray / vector with / without freeing it and monitored system memory behavior while running.

    Testing scenario I:


    struct mystruct{
      uint8_t* data; 
      //other fields may be here
    };
    
    int j = 0;
    while(1){
    
      j++;
    
      mystruct my;
      my.data = new uint8_t[1000000]; // approx. 1 MB
      for(int i=0;i<=1000000;i++){
        my.data[i] = 'A';
      }      
      std::deque<mystruct> d;
      d.push_back(my);
      // TBD: Need to delete/free data here, before d.pop_back()?
      // delete[] d[0].data;
      d.pop_back();
    
      Log(LogLevel::kInfo) << "pushing and popping ... " << j;
    
    }
    

    Testing scenario II:


      typedef struct mystruct{
        std::vector<uint8_t> data;
        // other fields may be here
      } mystruct_t;
    
      std::deque<mystruct_t> d;
    
        int j = 0;
        while(1){
    
          j++;
    
          mystruct my;      
          for(int i=0;i<=1000000;i++){  // approx. 1 MB
            my.data.push_back('A');
          }      
          std::deque<mystruct> d;
          d.push_back(my);
    
          // TBD: Need to delete/free data here, before d.pop_back()?      
          //  for(int i=0;i<=1000000;i++){  // approx. 1 MB
          //    d[0].data.pop_back();
          //  }  
    
          d.pop_back();
    
          Log(LogLevel::kInfo) << "pushing and popping ... " << j;
    
        }
    

    The results are:

    Additional remarks: Scenario II was much slower than Scenario I, especially when all the elements in the vector are popped each time.

    Would be happy if someone could explain why the memory allocated by the vector seems to be freed when the hosting deque-element is popped.