Функция возвращает символ * - PullRequest
       2

Функция возвращает символ *

1 голос
/ 09 сентября 2011

Правильно ли написать функцию, которая возвращает char *?

Примерно так:

char * func()
{  
 char *c = new char[3];
 strcpy(c, "hi");
 c[2] = '\0';
 return c;
}

int main()
{
 char *c;
 c = func();
 //code using c
 delete [] c;
 return 1;
}

Работает, но правильно ли?

Ответы [ 5 ]

6 голосов
/ 09 сентября 2011

Это правильно (при условии, что вы имели в виду strcpy, а не strlen), но из документации функции должно быть очень ясно, что вызывающая сторона несет ответственность за освобождение возвращаемого указателя, и какой метод он должен сделать используйте для его освобождения (new => delete, new [] => delete[], malloc => free и т. д.). Это «С» способ сделать это.

Это зависит от пользователей вашей функции (включая вас после нескольких месяцев, когда вы ее написали), чтобы прочитать документацию, чтобы все было правильно, так что она довольно подвержена ошибкам; Кроме того, в C ++ есть еще несколько сложностей, которых нет в C (а именно: исключения), которые делают использование необработанных указателей в этих контекстах не очень хорошей идеей.

Это причина, по которой вы обычно должны возвращать классы, которые инкапсулируют ресурсы (например, std::string в этом случае, и в общем случае контейнеры, которые управляют памятью автоматически) или интеллектуальные указатели, передающие права собственности, которые также имеют преимущество, заключающееся в исключении: безопасно (что ваш код не является).

Звучит крайне сложно, но на самом деле это не так:

#include <string>

std::string func()
{  
   return "hi"; // actually, to be more explicit it should be return std::string("hi")
}

int main()
{
    std::string c;
    c=func();
    return 1;
}

Вот и все, не нужно беспокоиться о распределении / освобождении и исключениях, все это автоматически обрабатывается классом std::string, поэтому вы можете управлять строками почти так же, как они были встроенными типами.

2 голосов
/ 09 сентября 2011

Это работает, но правильно ли?

Ваш код правильный .

Однако, это зависит от контекста, если это хорошая практика программирования или нет. Для этой минимальной программы, которую вы разместили, я предпочитаю не использовать new[] и delete[]. Но лучше полагаться на std::string.

Демо .

2 голосов
/ 09 сентября 2011

Ну, это работает.Память распределяется в куче и освобождается правильно.Нет необходимости вручную добавлять нулевой терминатор, поскольку strcpy делает это.

Но на самом деле это не C ++.В C ++ вы бы использовали std::string.

1 голос
/ 09 сентября 2011

Ваш код технически правильный. Тем не менее, я думаю, что у большинства SO здесь есть оговорки относительно того, считается ли он «хорошим» кодом или нет.

Для начала:

  • Выберите значимые имена переменных / функций. c и func не очень описательны и мешают другим понять, что вы пытаетесь сделать
  • Обычно у вас должна быть соответствующая функция, которая очищает любые ресурсы, выделенные вашей функцией.
  • Предпочитают strncpy() над strcpy(), чтобы предотвратить непредвиденное переполнение буфера (или заглянуть в класс String)
0 голосов
/ 09 сентября 2011

попробовать:

char * func()
{  
 char * c = new char[3];
 strcpy(c,"hi");
 return c;
}

int main()
{
 char *c;
 c = func();
 //code using c
 delete [] c;
 return 0;
}
...