Подтвердить что ты не робот

Как вернуть локальный массив в С++?

char *recvmsg(){
    char buffer[1024];
    return buffer;
}

int main(){
    char *reply = recvmsg();
    .....
}

Я получаю предупреждение:

предупреждение C4172: возврат адреса локальной переменной или временного

4b9b3361

Ответ 1

Вам необходимо динамически выделять массив char:

char *recvmsg(){
   char* buffer = new char[1024];
   return buffer;
}

для С++ и

char *recvmsg(){
   char* buffer = malloc(1024);
   return buffer;
}

для C.

Что происходит, без динамического распределения ваша переменная будет находиться в стеке функций и поэтому будет уничтожена при выходе. Вот почему вы получаете предупреждение. Выделение его на кучу предотвращает это, но вам придется быть осторожным и освобождать память, когда-то выполняемую с помощью delete[].

Ответ 2

Я бы предложил std::vector<char>:

std::vector<char> recvmsg()
{
    std::vector<char> buffer(1024);
    //..
    return buffer;
}
int main()
{
    std::vector<char> reply = recvmsg();
}

И если вам когда-нибудь понадобится char* в вашем коде, вы можете использовать &reply[0] в любое время. Например,

void f(const char* data, size_t size) {}

f(&reply[0], reply.size());

И все готово. Это означает, что если вы используете C API, вы все равно можете использовать std::vector, поскольку вы можете передать &reply[0] в API C (как показано выше) и reply в С++ API.

Нижняя линия: избегайте использования new как можно больше. Если вы используете new, тогда вы должны управлять им самостоятельно, и вы должны delete, когда вам это не понадобится.

Ответ 3

Предупреждающее сообщение верное. Вы возвращаете адрес локального массива, который исчезает после возвращения функции.

Вы можете сделать это, используя распределение динамической памяти:

char *recvmsg(){
    char *buffer = (char*)malloc(1024);
    return buffer;
}

Ловушка заключается в том, что вам нужно убедиться, что вы указали free() указатель позже, чтобы избежать утечки памяти.

В качестве альтернативы вы можете передать буфер в функцию.

void recvmsg(char *buffer,int buffer_size){
    //  write to buffer
}

void main(){
    char buffer[1024];
    recvmsg(buffer,1024);
}

Это позволяет избежать необходимости выделения памяти. Это действительно предпочтительный способ сделать это.

Ответ 4

Проблема заключается в том, что buffer живет в стеке и выходит из области видимости с момента выхода из recvmsg.

Вы можете выделить buffer в куче:

char *recvmsg(){
  char *buffer = malloc(1024);
  return buffer;
}

Обратите внимание, что теперь вызывающий абонент отвечает за распоряжение выделенной памятью:

void main(){
  char *reply = recvmsg();
  free(reply);
}

Ответ 5

Вы можете динамически создавать буфер, но затем вызывающий должен знать, чтобы освободить его.

Я думаю, что лучше пройти в буфере (при условии, что recvmsg также заполняет его)

void recvmsg(char *buffer, size_t size){

}

void main(){
    char buffer[1024];
    recvmsg(buffer, sizeof(buffer));
}

Даже если вызывающий решает динамику лучше, они будут знать, что им нужно ее освободить, и конкретный способ сделать это (free(), delete, delete [] или, возможно, что-то особенное из пользовательского распределителя)

Ответ 6

char *recvmsg(){
    char *buffer = new char;
    cout<<"\nENTER NAME : ";
    cin>> buffer;
    return buffer;
}

int main(){
    char *reply = recvmsg();
    cout<<reply;
}

Ответ 7

Только для завершения изображения:

Нет необходимости выделять память с помощью malloc. Вы также можете создать буфер в стеке, но вы должны создать его в кадре стека, который живет до тех пор, пока живет потребитель буфера. Это была ошибка OP - когда вызов был закончен, буфер был удален, а вызывающий получил недопустимый указатель.

Итак, что вы можете сделать, так это:

void recvmsg(char *buffer, size_t size) {
   ... do what you want ...
}

void main(void) {
    char buffer[1024];
    recvmsg(buffer, sizeof(buffer));
}

Ответ 8

Проблема заключается в том, что вы возвращаете указатель на буфер, выделенный в стеке. Как только функция вернется, этот буфер уже недействителен.

Ответ 9

Вы выделяете массив в стек внутри вашей функции recvmsg. Возврат указателя на эту память в какой-то момент приведет к поведению undefined, если он будет разыменован, поскольку память будет очищена, когда функция выйдет.

Если вы хотите вернуть указатель в память, вам нужно будет динамически выделять его с помощью malloc.

Ответ 10

У вас есть несколько вариантов... То, как вы сейчас это делаете, приведет к поведению undefined, поскольку массив выйдет из области действия после возврата функции hte. Таким образом, одним из вариантов является динамическое выделение памяти.

char * recmsg()
{ 
   char * array = new char[128];
   return array;
}

Не забудьте очистить его удалением таким образом (или бесплатно, если вы использовали malloc). Во-вторых, вы можете использовать параметр...

void recmsg(char * message, int size)
{
   if (message == 0)
      message = new char[size];
}

Опять же, то же самое происходит для очистки здесь, как и с предыдущим. Также обратите внимание на проверку на наличие 0, чтобы убедиться, что вы не вызываете новое по уже выделенному указателю.

Наконец, вы можете использовать вектор.

std::vector<char> recmsg()
{
   std::vector<char> temp;

   //do stuff with vector here

   return temp;
}

Ответ 11

когда вы возвращаете буфер, тогда как он действует как указатель на первое местоположение массива, чтобы он возвращал свой адрес. И там, где вы вызываете функцию, вы можете сделать указатель на символ, который будет хранить этот возвращаемое значение адреса. После этого вы можете переместить указатель и получить доступ ко всем элементам вашего массива.

Ответ 12

как насчет прохождения по ref

char buf[1024];
PutStuffInBuff(&buf);