Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Что возвращает новый [size_t] + 1

Автор вопроса: PeterОтветов: 6

Следующий пример кода из книги "C ++ von A bis Z" (второе издание, перевод: C ++ от A до Z) на странице 364. Образец неверен.

// overload operator +=
#include <iostream>
#include <cstring>
using namespace std;

class String {
private:
    char* buffer;
    unsigned int len;

public:
    String(const char* s="") {
        // cout << "Constructor: " << s << "\n";
        len = strlen(s);
        buffer = new char [len+1];
        strcpy(buffer, s);
    }
    ~String() {
        // cout << "Destructor: " << buffer << "\n";
        delete [] buffer;
    }
    String(const String& s) {
        // cout << "Copy_Constructor: " << s.get_buffer() << "\n";
        len = s.len;
        buffer = new char [len+1];
        strcpy(buffer, s.buffer);
    }
    char* get_buffer() const {
        return buffer;
    }

    // returning a reference is more efficent
    // String& operater+=(const String& str1)
    String operator+=(const String& str1) {
        // cout << "Assignment_Operator +=: " << str1.get_buffer() << "\n";
        String tmp(*this);
        delete [] buffer;
        len = tmp.len + str1.len;
        // invalid pointer
        // buffer = new char[len+1];
        buffer = new char [len]+1;
        strcpy(buffer, tmp.buffer);
        strcat(buffer, str1.buffer);
        // wrong return_type
        // return *this;
        return buffer;
    }
};

int main(void) {
    String string1("Adam");
    String string2("Eva");
    string1+=" und ";
    string1.operator+=(string2);
    cout << string1.get_buffer() << "\n";
    return 0;
}

Строки с комментариями - мои "исправления". Теперь я хочу знать, что делает "new char [len] +1"? Думаю следующее:

  • он выделяет sizeof (char) * len память из кучи
  • и возвращает НЕПРАВИЛЬНЫЙ адрес указателю * буфер
  • но каков неправильный адрес: "первый адрес новой памяти в куче + 1" или "первый адрес новой памяти в куче + sizeof (char) * 1)?

Что случается? Спасибо

// редактировать Всем спасибо! Ты мне помог! Я просто хотел знать, что вернет это заявление.

new char [len]+1;

Сама строчка, конечно же, опечатка автора книги.

  • Чем отличается ваш третий пункт? sizeof(char) == 1 по определению. Kerrek SB 09.12.2011
  • Кроме того, кому наплевать - если вы занимаетесь C ++, забудьте о char* и strcpy и необработанных массивах. Kerrek SB 09.12.2011
  • Думаю, вы правы во всех своих предположениях. Возвращаемый адрес - это первый адрес новой памяти в куче + sizeof (char) * 1, но в любом случае это не имеет смысла для этого кода. Lyth 09.12.2011
  • Это обряд посвящения или что-то в этом роде, написание собственного строкового класса. Не могу сказать, что поняла, учитывая std::string, но да. cHao 09.12.2011
  • @KerrekSB: все это очень хорошо говорит новичкам забыть о char*, но вы уверены, что хотите, чтобы они не понимали, почему "hello, " + "world" не работает? В конечном итоге они спросят о SO, и их будут упрекать за то, что они не знают о char*. Реализация строкового класса, возможно, больше, чем им строго нужно, но я бы предпочел, чтобы они примерно знали, как он работает. Steve Jessop 09.12.2011
  • @cHao: это потому, что одна из интересных вещей в дизайне C ++ заключается в том, что вы предполагалось иметь возможность реализовать этот и аналогичные классы в пользовательском режиме (под этим я подразумеваю отсутствие необходимости в специальном компиляторе / поддержка времени выполнения или оптимизированный код, написанный на других языках) с не большими накладными расходами, чем стандартная реализация. Конечно, не многие люди на самом деле используют этот аспект C ++ в своей повседневной жизни, но если вы собираетесь изучать C ++, вы можете также изучить его предполагаемые основные. Steve Jessop 09.12.2011

c++returnnew-operatorpointers

Ответы

Ответ 1 · рейтинг 4 · Luchian Grigore

Давайте разберемся:

new char[len];

возвращает указатель на массив char.

new char[len] + 1;

возвращает следующий адрес в памяти.

По сути, это отключение первого символа.

РЕДАКТИРОВАТЬ: Как уже упоминали другие, это, скорее всего, опечатка, это должно быть new char[len+1]. Я просто объясняю, что делает код, но вам следует использовать арифметику указателей, только если вы действительно знаете, что делаете. Как указал Чао, попытка удалить возвращенный указатель будет UB. Вы также получите UB, если len == 1, и попытаетесь работать с возвращенным указателем.

Ответ 2 · рейтинг 1 · sepp2k

Если вы добавите целое число i к T*, это добавит sizeof(T) * i к указателю. В этом случае, поскольку new char[len] возвращает char*, + 1 действительно добавит к нему sizeof(char) * 1.

Ответ 3 · sharptooth

new Type[size] + 1 выделит массив размером size и выдаст адрес элемента с индексом 1 - второго элемента. Ничего особенного, просто арифметика с указателями. new[] даст адрес элемента с индексом 0, а размер +1 выполняется по этому адресу, он дает адрес элемента с индексом 1.

Ответ 4 · shybovycha

Просто возвращает указатель на второй элемент массива =) Прочтите про указатели C;)

Ответ 5 · Michael Krelin - hacker

+sizeof(char)*1, но я не понял, зачем вы это сделали.

Ответ 6 · Some programmer dude

Я думаю, что это опечатка, и это должно быть new char [len+1]. +1 предназначен для символа терминатора строки, который должен существовать.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы