C++: возвращение локальной переменной

Модератор: Модераторы разделов

dronord
Сообщения: 40
ОС: slackware

C++: возвращение локальной переменной

Сообщение dronord »

Здравствуйте, извините за каламбур в названии темы =)

Расскажите, пожалуйста, технику возвращения локальной переменной.

Хочется иметь такой код:

Код:

#include <iostream> using std::cout; using std::endl; char *f1() { char x[] = {"xxx"}; return x; } int main(int argc, char* argv[]) { cout << f1() << endl; return 0; }


а приходится иметь такой:

Код:

char *f1() { char x[] = {"xxx"}; return strdup(x); } int main(int argc, char* argv[]) { char *r = 0; r = f1(); cout << r << endl; free®; return 0; }


неудобно =(
Спасибо сказали:
spielmann
Сообщения: 105
ОС: Linux

Re: C++: возвращение локальной переменной

Сообщение spielmann »

Можно string использовать:

Код: Выделить всё

string foo()
{
    string rc = "123";
    return rc;
}


Или [cm]alloc|strdup для char*.

Функция возвращает копию переменной. В случае со string - создаётся новый объект, который и возвращается. В случае с char* - копия указателя, но не области памяти.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: C++: возвращение локальной переменной

Сообщение v04bvs »

Код: Выделить всё

#include <iostream>
using std::cout;
using std::endl;

char *f1()
{
    char *x = "xxx";
    return x;
}

int main(int argc, char* argv[])
{
    cout << f1() << endl;
    return 0;
}
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: C++: возвращение локальной переменной

Сообщение dronord »

spielmann писал(а):
07.08.2007 12:02
Или [cm]alloc|strdup для char*.
В случае с char* - копия указателя, но не области памяти.


По поводу string - уже поезд ушел, ошибка в готовом проекте.

В случае с char* - ничего не понятно. strdup выделит память с помощью malloc, значит её надо где-то освободить. Иначе утечка.
Неужели, чтобы написать

Код:

strcat( s, f1() );
необходимо создавать временную переменную?
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: C++: возвращение локальной переменной

Сообщение Zeus »

Раз речь о C++ - юзай string'и. Зачем эти char*?
Спасибо сказали:
spielmann
Сообщения: 105
ОС: Linux

Re: C++: возвращение локальной переменной

Сообщение spielmann »

dronord писал(а):
07.08.2007 12:13
В случае с char* - ничего не понятно. strdup выделит память с помощью malloc, значит её надо где-то освободить. Иначе утечка.
Неужели, чтобы написать

Код: Выделить всё

strcat( s, f1() );
необходимо создавать временную переменную?


Если

Код: Выделить всё

char *f()
{
    char *x = "xxx";
    return x;
}


,то ничего освободжать не надо (память для "xxx" выделена статически) - можно оставить strcat(s, f()).
Но, если память где-то выделена динамически, то после использования, её нужно освободить.
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: C++: возвращение локальной переменной

Сообщение dronord »

Zeus, string'и не могу, много года править. Только если придется, то уж не отделаюсь.
spielmann, в случае

Код:

char *f() { char *x = "xxx"; return x; }

переменная уничтожается после выхода из ф-ии, значит результат будет непредсказуемым.
В MSVC++ 2005 Express Edition ф-я возвращает какой-то мусор;
В gcc-3.4.6 - что-нибудь, например "хх".
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: C++: возвращение локальной переменной

Сообщение serzh-z »

dronord писал(а):
07.08.2007 13:48
переменная уничтожается после выхода из ф-ии, значит результат будет непредсказуемым.
Какая ещё переменная??? Из функции возвращается указатель на константу "xxx"... Собственно, выше уже про это сказали.
Спасибо сказали:
Аватара пользователя
inline
Сообщения: 72
ОС: Gentoo

Re: C++: возвращение локальной переменной

Сообщение inline »

dronord писал(а):
07.08.2007 13:48
Zeus, string'и не могу, много года править. Только если придется, то уж не отделаюсь.
spielmann, в случае

Код:

char *f() { char *x = "xxx"; return x; }

переменная уничтожается после выхода из ф-ии, значит результат будет непредсказуемым.
В MSVC++ 2005 Express Edition ф-я возвращает какой-то мусор;
В gcc-3.4.6 - что-нибудь, например "хх".

а можно сделать переменную статической:

Код: Выделить всё

char *f()
{
    static char x[0xff] = "xxx";
    /* если функция должна возвращать разные значения */
    if (smth)
        strcpy(x, "yyy");
    return x;
}


только чем больше статических переменных, тем больше программа потребляет памяти, и тем дольше загружается (т. к. каждая статическая переменная инициализируется при запуске).
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: C++: возвращение локальной переменной

Сообщение dronord »

serzh-z писал(а):
07.08.2007 13:55
dronord писал(а):
07.08.2007 13:48
переменная уничтожается после выхода из ф-ии, значит результат будет непредсказуемым.
Какая ещё переменная??? Из функции возвращается указатель на константу "xxx"... Собственно, выше уже про это сказали.

Извиняюсь, не заметил указатель. Теперь я не понимаю разницы между char x[]= "xxx" и char *x= "xxx". Могу понять так:
x[] - это переменная, *x - указатель. Если возвращается указатель, где хранится его значение и надо ли его освобождать?
Спасибо сказали:
Аватара пользователя
inline
Сообщения: 72
ОС: Gentoo

Re: C++: возвращение локальной переменной

Сообщение inline »

dronord писал(а):
07.08.2007 14:03
serzh-z писал(а):
07.08.2007 13:55
dronord писал(а):
07.08.2007 13:48
переменная уничтожается после выхода из ф-ии, значит результат будет непредсказуемым.
Какая ещё переменная??? Из функции возвращается указатель на константу "xxx"... Собственно, выше уже про это сказали.

Извиняюсь, не заметил указатель. Теперь я не понимаю разницы между char x[]= "xxx" и char *x= "xxx". Могу понять так:
x[] - это переменная, *x - указатель. Если возвращается указатель, где хранится его значение и надо ли его освобождать?

x[] - память для массива символов выделяется на стеке: при выходе из функции он разрушается.
*x - указатель на константный массив. Он хранится в read-only памяти, освобождать его не нужно.
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: C++: возвращение локальной переменной

Сообщение serzh-z »

dronord писал(а):
07.08.2007 14:03
Если возвращается указатель, где хранится его значение и надо ли его освобождать?
В char[] - массив байт (указатель на первый элемент цепочки байт), char * - указатель первый элемент цепочки байт (массив байт). Фактической разницы нет.
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: C++: возвращение локальной переменной

Сообщение dronord »

Кажется, я разобрался. Случай с char x[] = {"xxx"}; выбрал неудачный, у меня инициализация не константой, а вычисляемым значением. Надо сразу передавать в ф-ю переменную под результат, можно её и вернуть, чтобы было удобно пользоваться. Т.е. я имею ввиду следующее:

Код:

#include <iostream> using std::cout; using std::endl; char *f1(char *x) { strcpy(x, "xxx"); return x; } int main(int argc, char* argv[]) { char rс[5]; cout << f1(rс) << endl; return 0; }
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: C++: возвращение локальной переменной

Сообщение serzh-z »

P.S.
dronord писал(а):
07.08.2007 14:03
и надо ли его освобождать?
В случае char[] - функция f вернет указатель на указатель в стеке.
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: C++: возвращение локальной переменной

Сообщение dronord »

inline, что это за память?
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: C++: возвращение локальной переменной

Сообщение serzh-z »

dronord писал(а):
07.08.2007 14:21
что это за память?
Обычный сегмент, помеченный битом "только для чтения".
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: C++: возвращение локальной переменной

Сообщение dronord »

Куча? Когда эта память освободится?
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: C++: возвращение локальной переменной

Сообщение serzh-z »

dronord, нет. Освободиться при завершении последнего экземпляра приложения, которое было запущено из *того-же самого* бинаря.
Спасибо сказали:
spielmann
Сообщения: 105
ОС: Linux

Re: C++: возвращение локальной переменной

Сообщение spielmann »

dronord писал(а):
07.08.2007 14:18
Кажется, я разобрался. Случай с char x[] = {"xxx"}; выбрал неудачный, у меня инициализация не константой, а вычисляемым значением. Надо сразу передавать в ф-ю переменную под результат, можно её и вернуть, чтобы было удобно пользоваться. Т.е. я имею ввиду следующее:

Код:

#include <iostream> using std::cout; using std::endl; char *f1(char *x) { strcpy(x, "xxx"); return x; } int main(int argc, char* argv[]) { char rс[5]; cout << f1(rс) << endl; return 0; }


В данном конкретном примере, нужно хотя бы проинициализированть элементы массива rc[]. Т.е.:

Код: Выделить всё

#include <iostream>
#include <strings.h>

using std::cout;
using std::endl;

char *f1(char *x)
{
    strcpy(x, "xxx");
    return x;
}

int main(int argc, char* argv[])
{
    char rс[5];
    bzero(rc, sizeof(rc));
    cout << f1(rс) << endl;
    return 0;
}

Т.к. строки (правильные) терминируются символом c кодом 0x0.
И ещё: в f1() ничего неизвестно о размере выделенной памяти, на которую указывает x.
Спасибо сказали:
dronord
Сообщения: 40
ОС: slackware

Re: C++: возвращение локальной переменной

Сообщение dronord »

Коллеги спасибо!
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: C++: возвращение локальной переменной

Сообщение v04bvs »

char* x = "xxx";
аналогично
static const char* const GLOBAL_XXX = "xxx"; // глобальная переменная

...
char* x = GLOBAL_XXX;

char[] x = "xxx";
аналогично
char[4] x = {'x', 'x', 'x', 0};
(т.е. примерно так:
char x0 = 'x';
char x1 = 'x';
char x2 = 'x';
char x3 = 0;
)
Спасибо сказали: