Установка указателя на новый буфер длиной n

#c

#c

Вопрос:

Я пытаюсь воссоздать урезанную версию класса STL string. Я пытаюсь реализовать конструктор, который будет принимать c-строку в качестве аргумента.

 inline String::String(const char* s)
{
    buffer = get_new_buffer(s);
    size = strlen(s);
}
  

Чтобы установить указатель, я написал функцию get_new_buffer(char* n) const для перераспределения нового буфера для строки и для установки указателя на новый буфер.

 inline char* String::get_new_buffer(char* n) const
{
    return (strlen(n) == 0 ? nullptr : new char* [strlen(n)]());
}
  

У меня возникла проблема с get_new_buffer возвратом функции. Это говорит мне, что возвращаемый тип не соответствует типу функции, но почему это должно быть? Почему в моем операторе return он не возвращает указатель на новый буфер и что мой должен возвращать?

Комментарии:

1. Что это за тип buffer ? Также функция new buffer должна возвращать new char[strlen(n)] , иначе там будет дополнительный уровень указателя

2. Вы хотите new char [strlen(n)]()); . В противном случае вы имеете в виду массив char* указателей.

3. В информатике есть две сложные проблемы: присвоение имен, аннулирование кэша и ошибка «один за другим», я предполагаю, что у вас возникли проблемы с последним. Сколько места вам нужно для хранения строки?

4. И следите за своими const с.

5. @jjramsey нет ничего плохого в том, чтобы поместить () after new char[] , по крайней мере, в C 11 и более поздних версиях, это просто инициализирует выделенные char s по значению '' .

Ответ №1:

С этим кодом связано несколько проблем:

  • get_new_buffer() объявлено, что возвращает char* указатель, но выделяет char*[] массив, который распадается на char** указатель. Это несоответствие, на которое жалуется компилятор. Удалите лишнее * для типа элемента массива. Вам нужен массив char s, а не массив указателей на char .

  • код не копирует char элементы входной s строки в выделенный buffer .

  • код не проверяет, есть ли s nullptr . Вызов strlen() с nullptr вводом — это неопределенное поведение.

Вместо этого попробуйте что-то более похожее:

 inline String::String(const char* s)
{
    buffer = get_new_buffer(s, size);
}

inline char* String::get_new_buffer(const char* n, size_t amp;size) const
{
    char *buffer;
    size_t bufsize = (n != nullptr) ? strlen(n) : 0;
    if (bufsize > 0) {
        buffer = new char[bufsize   1];
        strcpy(buffer, n);
    }
    else
        buffer = nullptr;
    size = bufsize;
    return buffer;
}