char *recvmsg(){
char buffer[1024];
return buffer;
}
int main(){
char *reply = recvmsg();
.....
}
Я получаю предупреждение:
предупреждение C4172: возврат адреса локальной переменной или временного
char *recvmsg(){
char buffer[1024];
return buffer;
}
int main(){
char *reply = recvmsg();
.....
}
Я получаю предупреждение:
предупреждение C4172: возврат адреса локальной переменной или временного
Вам необходимо динамически выделять массив char:
char *recvmsg(){
char* buffer = new char[1024];
return buffer;
}
для С++ и
char *recvmsg(){
char* buffer = malloc(1024);
return buffer;
}
для C.
Что происходит, без динамического распределения ваша переменная будет находиться в стеке функций и поэтому будет уничтожена при выходе. Вот почему вы получаете предупреждение. Выделение его на кучу предотвращает это, но вам придется быть осторожным и освобождать память, когда-то выполняемую с помощью delete[]
.
Я бы предложил 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
, когда вам это не понадобится.
Предупреждающее сообщение верное. Вы возвращаете адрес локального массива, который исчезает после возвращения функции.
Вы можете сделать это, используя распределение динамической памяти:
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);
}
Это позволяет избежать необходимости выделения памяти. Это действительно предпочтительный способ сделать это.
Проблема заключается в том, что buffer
живет в стеке и выходит из области видимости с момента выхода из recvmsg
.
Вы можете выделить buffer
в куче:
char *recvmsg(){
char *buffer = malloc(1024);
return buffer;
}
Обратите внимание, что теперь вызывающий абонент отвечает за распоряжение выделенной памятью:
void main(){
char *reply = recvmsg();
free(reply);
}
Вы можете динамически создавать буфер, но затем вызывающий должен знать, чтобы освободить его.
Я думаю, что лучше пройти в буфере (при условии, что recvmsg также заполняет его)
void recvmsg(char *buffer, size_t size){
}
void main(){
char buffer[1024];
recvmsg(buffer, sizeof(buffer));
}
Даже если вызывающий решает динамику лучше, они будут знать, что им нужно ее освободить, и конкретный способ сделать это (free(), delete, delete [] или, возможно, что-то особенное из пользовательского распределителя)
char *recvmsg(){
char *buffer = new char;
cout<<"\nENTER NAME : ";
cin>> buffer;
return buffer;
}
int main(){
char *reply = recvmsg();
cout<<reply;
}
Только для завершения изображения:
Нет необходимости выделять память с помощью malloc. Вы также можете создать буфер в стеке, но вы должны создать его в кадре стека, который живет до тех пор, пока живет потребитель буфера. Это была ошибка OP - когда вызов был закончен, буфер был удален, а вызывающий получил недопустимый указатель.
Итак, что вы можете сделать, так это:
void recvmsg(char *buffer, size_t size) {
... do what you want ...
}
void main(void) {
char buffer[1024];
recvmsg(buffer, sizeof(buffer));
}
Проблема заключается в том, что вы возвращаете указатель на буфер, выделенный в стеке. Как только функция вернется, этот буфер уже недействителен.
Вы выделяете массив в стек внутри вашей функции recvmsg
. Возврат указателя на эту память в какой-то момент приведет к поведению undefined, если он будет разыменован, поскольку память будет очищена, когда функция выйдет.
Если вы хотите вернуть указатель в память, вам нужно будет динамически выделять его с помощью malloc
.
У вас есть несколько вариантов... То, как вы сейчас это делаете, приведет к поведению 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;
}
когда вы возвращаете буфер, тогда как он действует как указатель на первое местоположение массива, чтобы он возвращал свой адрес. И там, где вы вызываете функцию, вы можете сделать указатель на символ, который будет хранить этот возвращаемое значение адреса. После этого вы можете переместить указатель и получить доступ ко всем элементам вашего массива.
как насчет прохождения по ref
char buf[1024];
PutStuffInBuff(&buf);