Возврат по полученному массиву char [duplicate]

Переменная интерполяция не происходит в одинарных кавычках. Вам нужно использовать двойные кавычки как:

$i = 1
echo "<p class=\"paragraph$i\"></p>";
++i;
20
задан Pang 15 January 2016 в 02:26
поделиться

12 ответов

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

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

для C ++ и

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

для C.

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

11
ответ дан Luchian Grigore 15 August 2018 в 14:26
поделиться
  • 1
    Использование new в C ++ не делает его решением в стиле C ++. Решение C ++ - это std::vector<char> вместо необработанного указателя char*. – Nawaz 14 October 2011 в 16:53
  • 2
    вы не можете использовать std :: vector с p / invoke, насколько я знаю, если у вас есть какие-либо взаимодействия с c # или VB – Tom Fobear 14 October 2011 в 18:11
  • 3
    не лучше malloc( 1024 * sizeof( char ) )? – sazary 11 August 2013 в 00:21
  • 4
    @sazary вопрос предпочтения, sizeof char всегда 1. – Luchian Grigore 11 August 2013 в 13:47
  • 5
    Нет необходимости, что malloc используется, см. Ответ карла или моего. – Juergen 17 February 2015 в 01:41

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

char buf[1024];
PutStuffInBuff(&buf);
-1
ответ дан AbcAeffchen 15 August 2018 в 14:26
поделиться
  • 1
    Я предполагаю, что karl означает, что вызывающий оператор ссылается на buf, и вызывающий набирает buf. Поскольку вызывающий абонент живет дольше, как вызываемый (и так же buf, все нормально, если вызывающий не возвращает ссылку на buf). – Juergen 17 February 2015 в 01:40

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

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

0
ответ дан Ed S. 15 August 2018 в 14:26
поделиться

Просто для завершения изображения:

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

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

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

void main(void) {
    char buffer[1024];
    recvmsg(buffer, sizeof(buffer));
}
1
ответ дан Juergen 15 August 2018 в 14:26
поделиться

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

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

void recvmsg(char *buffer, size_t size){

}

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

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

1
ответ дан Lou Franco 15 August 2018 в 14:26
поделиться

У вас есть несколько вариантов ... То, как вы сейчас это делаете, приведет к неопределенному поведению, поскольку массив выйдет из области действия после возврата функции 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;
}
0
ответ дан MGZero 15 August 2018 в 14:26
поделиться

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

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

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);
}

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

10
ответ дан Mysticial 15 August 2018 в 14:26
поделиться
  • 1
    +1 для альтернативы. Многие функции C работают таким образом, и есть причина, почему. – netcoder 14 October 2011 в 16:39
  • 2
    Так оно и должно быть. +1 – Andrejs Cainikovs 14 October 2011 в 16:39
  • 3
    Я бы, конечно, not предложил это. В C ++ std::vector<char> - лучшее решение. Этот ответ предлагает решение C-стиля, но вопрос связан с C ++. – Nawaz 14 October 2011 в 16:46
  • 4
    Почему у меня сложилось впечатление, что он был помечен C ... Но да, вы правы, вектор предпочтительнее. – Mysticial 14 October 2011 в 16:49

Я бы предложил 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] в C API (как показано выше) и reply в C ++ API.

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

25
ответ дан Nawaz 15 August 2018 в 14:26
поделиться

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

0
ответ дан Nitesh Narayan Lal 15 August 2018 в 14:26
поделиться

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

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

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

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

void main(){
  char *reply = recvmsg();
  free(reply);
}
5
ответ дан NPE 15 August 2018 в 14:26
поделиться
  • 1
    Большинство ответов действительно, но только вы упомянули free (). Я бы поставил комментарий между двумя строками в main (): /* do stuff here*/, для удобства чтения. +1 – Andrejs Cainikovs 14 October 2011 в 16:37
  • 2
    Но если я освобожу (ответ), я уничтожу результат и как я могу использовать результат позже в своем коде? – Andreyua 1 April 2015 в 19:50
char *recvmsg(){
    char *buffer = new char;
    cout<<"\nENTER NAME : ";
    cin>> buffer;
    return buffer;
}

int main(){
    char *reply = recvmsg();
    cout<<reply;
}
1
ответ дан Shubhankar Sisodia 15 August 2018 в 14:26
поделиться

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

0
ответ дан TJD 15 August 2018 в 14:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: