Как правильно получить указатель на строку в стиле C в качестве аргумента и иметь возможность выделить память или изменить ее?

У меня есть следующий метод подписи:

int get_name(char* &name_out);

То, что я хотел бы сделать, это выделить память размером с name за name_out а затем скопируйте содержимое name в name_out,

Или было бы лучше изменить его на:

int get_name(char &name_out[], int size);

и позволить пользователю функции сначала выделить и отследить память, и вернуть ошибку, если размер данного массива недостаточно велик, чтобы содержать строку?

Единственное, что мне не нравится в этом, это то, что это потребует от пользователя get_name() функция, чтобы иметь представление о длине строки имени.

Я чувствую, что было бы избыточно иметь две функции int get_name_length(); а также get_name(char* name_out);

Поскольку это часть задания по программированию, существуют условия:

  1. Строковый класс не допускается.
  2. Строки в стиле C должны быть использованы.
  3. Векторы не могут быть использованы.
  4. Функция должна возвращать int для обозначения ошибки.
  5. Обработка исключений не допускается.

Спасибо.

0

Решение

Стандартный способ C сделать это — передать в функцию два указателя:

int getName(char** name_out, size_t* size_out);

Это имеет несколько преимуществ:

  • Вызывающая сторона свободна предварительно выделить память / повторно использовать выделение.

  • Вызываемый может свободно отрегулировать распределение с помощью realloc() (при условии, что строка в стиле C выделена с malloc()) или через пару delete[]/new[],

  • Получение адреса является явным. То есть на сайте звонка вы бы написали:

    char* name = null_ptr;
    size_t size = 0;
    if(getName(&name, &size)) handleError();
    

    Явный & Оператор очень ясно дает понять, что функция getName() может изменить обе переменные. Если вы идете со ссылками, вы не можете различить вызов по ссылке и вызов по значению, не глядя на объявление функции.

Также обратите внимание, что тип, используемый для размеров размещения size_t: это тип, который гарантированно сможет содержать размер всего используемого адресного пространства.

0

Другие решения

Если я правильно понимаю, что вы пытаетесь сделать, это реализовать вариант для ‘strcpy’.

Основное различие заключается в том, что вы передаете ответственность за распределение своей функции копирования, в то время как strcpy оставляет ее пользователю. Если это производственный код, то я рекомендую следовать подходу «strcpy», к которому привыкла отрасль.

Если это только для игры, оберните strcpy функцией, которая выполняет выделение, и придерживайтесь интерфейса strcpy.

1

По вопросам рекламы [email protected]