Как изменить размер массива уникальных указателей, принадлежащих классу.Это должно быть сохранено в течение всей жизни программы - PullRequest
0 голосов
/ 27 января 2019

У меня есть класс с именем container, содержащий std :: unique_ptr _ptr.Этот _ptr должен поддерживаться в течение всего процесса программы.Я не могу это потерять.Когда, наконец, контейнерный объект уничтожен.Он будет уничтожен вместе с ним.

В какой-то части программы.Мне нужно добавить символ в массив _ptr.Для этой цели я использую следующую функцию:

void resizeUniquePtrArray(std::unique_ptr<char[]> &ptr) {
   std::unique_ptr<char[]> newptr(new char[strlen(ptr.get())+2]);
  memcpy(newptr.get(), ptr.get(),strlen(ptr.get()));
  newptr[strlen(newptr.get())]= 'X';
  newptr[strlen(newptr.get()) + 1]= '\0';
  ptr = std::move(newptr);
}

Ограничения

Я почти уверен, что делаю что-то не так.В моем проекте Иногда я теряю содержание _ptr, а иногда нет.Самое смешное, что valgrind не выдал никаких предупреждений.

  • Я не могу использовать строку вместо std :: unique_ptr, потому что мне придется использовать позже в const_cast, это все равно что изнасиловать строкучто я создал.

  • Я попытался использовать vector и присвоить его char * с помощью .data ().Но Вальгринд сошел с ума и дал мне всевозможные ошибки чтения и записи

  • Проблема в библиотеке C с ее char * rawPointer.Это действительно трудно обойти.Я не могу просто использовать новый символПотому что мне придется носить его с собой через всю программу.

Вопрос

Правильно ли выполнено изменение размера массива уникальных указателей Char _ptr?

Исходный код

#include <iostream>
#include <string>
#include <memory> 
#include <string.h>

class Container {
    public:
     Container(const std::string &data):_data(data),_ptr(new char[data.size() + 1]) {}

     std::unique_ptr<char[]> & initPtr(){
         strcpy(_ptr.get(),_data.c_str());
         _ptr[strlen(_ptr.get()) + 1] = '\0';
         return _ptr;
     }
     private:
       std::unique_ptr<char[]> _ptr;
       std::string _data;
};

void resizeUniquePtrArray(std::unique_ptr<char[]> &ptr) {
   std::unique_ptr<char[]> newptr(new char[strlen(ptr.get())+2]);
  memcpy(newptr.get(), ptr.get(),strlen(ptr.get()));
  newptr[strlen(newptr.get())]= 'X';
  newptr[strlen(newptr.get()) + 1]= '\0';
  ptr = std::move(newptr);
}

int main()
{
  std::string name = "hello";
  Container c(name);
  std::unique_ptr<char[]> &ptr = c.initPtr();
  resizeUniquePtrArray(ptr);

  char* rawPointer = ptr.get();
  std::cout<< rawPointer << std::endl;

  //API LIBRARY CALL TO rawPointer it's a looonng process

  return 0;
}

1 Ответ

0 голосов
/ 27 января 2019

Я не могу использовать std::string вместо std::unique_ptr, потому что мне придется использовать позже const_cast, это все равно что изнасиловать созданную мной строку.

Нет const_cast необходимо для получения простого указателя на нижележащую C-строку:

std::string s("abc");
char* p = &s[0];

Или в C ++ 17:

char* q = s.data();
...