Как вернуть из функции структуру?

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by herfleisch, 31 Jan 2009.

  1. herfleisch

    herfleisch Elder - Старейшина

    Joined:
    7 Jan 2009
    Messages:
    578
    Likes Received:
    203
    Reputations:
    13
    Собственно, вопрос по C/C++ - как вернуть из функции структуру? Пробовал в функции создать структуру, вернуть на неё указатель. В Debug-режиме работает. В реальности - нет. Какие есть идеи?
     
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    все данные созданные внутри процедуры распологаются в стеке и по этому после выполнения данной процедуры могут затереться и вообще всё что угодно может стать потом с ними. По этому лучше структуру создавай отдельно, а функции передавай указатель на неё.

    Примерно так:
    Code:
    typedef struct _PARAMS {
     ULONG p1;
     ULONG p2;
     ULONG p3;
    } PARAMS,* PPARAMS;
    
    
    VOID proc1(PPARAMS p)
    {
    // работаешь как с указателем
    p->p1=1;
    p->p2=2;
    p->p3=3;
    }
    
    VOID main(VOID)
    {
     PARAMS param;
    
     proc1(&param); 
     z=param.p1+param.p2+param.p3;
    }
    
     
    #2 slesh, 31 Jan 2009
    Last edited: 31 Jan 2009
    1 person likes this.
  3. groundhog

    groundhog Elder - Старейшина

    Joined:
    12 May 2007
    Messages:
    1,159
    Likes Received:
    425
    Reputations:
    180
    Всё верно, на вход в функцию передавай указатель на инициализированную структуру, внутри функции меняй её и в случае успеха возвращай флаг успеха...
     
    2 people like this.
  4. herfleisch

    herfleisch Elder - Старейшина

    Joined:
    7 Jan 2009
    Messages:
    578
    Likes Received:
    203
    Reputations:
    13
    Да... вы правы... Спасибо всем за ответы.
     
  5. herfleisch

    herfleisch Elder - Старейшина

    Joined:
    7 Jan 2009
    Messages:
    578
    Likes Received:
    203
    Reputations:
    13
    А если речь идёт о структуре, полями которой являются массивы типа char ???
     
  6. groundhog

    groundhog Elder - Старейшина

    Joined:
    12 May 2007
    Messages:
    1,159
    Likes Received:
    425
    Reputations:
    180
    herfleisch, ну а какая разница? ты же передаёшь уже инициализированную структуру... То есть даже поля сhar* будут инициализированы...
     
  7. herfleisch

    herfleisch Elder - Старейшина

    Joined:
    7 Jan 2009
    Messages:
    578
    Likes Received:
    203
    Reputations:
    13
    Да... спасибо =) Было лень подумать =)
     
  8. .Slip

    .Slip Elder - Старейшина

    Joined:
    16 Jan 2006
    Messages:
    1,571
    Likes Received:
    976
    Reputations:
    783
    Так попроще думаю будет:
    Code:
    #include <iostream>
    using namespace std;
    
    struct TEST
    {
    	char* Var;
    	char* Var2; 
    } Obj;
    
    void pstruct(TEST &);
    
    int main()
    {
    	pstruct(Obj);
    
    	cout << Obj.Var << endl
    		<< Obj.Var2 << endl;
    	return 0;
    }
    
    void pstruct(TEST &rObj)
    {
    	rObj.Var = "teeeest";
    	rObj.Var2 = "mdaaaa";
    }
     
    #8 .Slip, 31 Jan 2009
    Last edited: 31 Jan 2009
    1 person likes this.
  9. xismyname

    xismyname Elder - Старейшина

    Joined:
    7 Sep 2008
    Messages:
    77
    Likes Received:
    7
    Reputations:
    -5
    Надо же,столько ответов,и ни один не ответил на вопрос "Как вернуть структуру из функции ?"

    Как уже отмечалось,все локальные переменные распологаються в stack-e,после выполнении данной функции они удаляються/перезаписываються - поэтому придеться создать указатель на функцию и динамически занять место в памяти.

    Пример :
    Code:
    [COLOR=Sienna]#include <stdio.h>[/COLOR]
    
    /* Наша структура */
    [COLOR=RoyalBlue]struct{
        unsigned char name[16];
        unsigned int  age;
    }MyStruct;
    [/COLOR]
    
    
    /* функция которая возвращает указатель на структуру MyStruct */[COLOR=RoyalBlue]
    struct MyStruct *MyFunc(void)
    {[/COLOR]
       /* Создаем указатель и аллокируем место в памяти */
       [COLOR=RoyalBlue]struct MyStruct *r_struct = (struct MyStruct*)malloc(sizeof(struct MyStruct));[/COLOR]
       
       /* Если аллокация памяти прошла успешно - заполняем структуру и
          возвращаем указатель на данную структуру,в другом случаи
          возвращаем NULL.
       */
       [COLOR=RoyalBlue]if( r_struct != NULL )
       {
           r_struct->name[] = "MyName";
           r_struct->age    = 17;
           return r_struct;
       }
       else
       {
           return NULL;
       }
    }
       
    
    
    int main(void)
    {[/COLOR]
        /* Тут мы уже создаем только указатель на структуру,аллокировать
           память нам не приходиться так,как, она уже аллокирована 
           функцией MyFunc() и будет доступно нам до конца программы,
           пока не освободим ее с помощью функции free() 
        */
         
       [COLOR=RoyalBlue] struct MyStruct *r_getStruct = MyFunc();
        
        if( r_getStruct != NULL )
        {
            printf("Name : %s\n", r_getStruct->name);
            printf("Age  : %d\n", r_getStruct->age);
            free((void*)r_getStruct);
            return 0;
        }
        else
        {
            return -1;
        }
    }[/COLOR]
    Чтобы все время не писать перед идентификатором структуры struct лучше создать как новый тип т.е. с помощью typedef .
     
    1 person likes this.
  10. awdrg

    awdrg Member

    Joined:
    30 Jan 2009
    Messages:
    195
    Likes Received:
    31
    Reputations:
    1
    все просто:

    Code:
    // простой код, передает в функцию две структуры
    // и возвращает одну, с суммами значений введенных.
    // By awdrg
    #include <iostream>
    using namespace std;
    
    struct test
    {
       int value_1;  //первое значение
       int value_2;  //второе значение
    };
    
    test func(test, test);  // в скобках ставь свои входные данные.
                            // обрати внимание, в начале прототипа стоит
                            // имя структуры, которая будет возвращаться
    main()
    {
       test one={10,20};   //инициализация
       test two ={30,40};  //инициализация
       test summ = func(one, two);  //инициализация с вызовом функции, возвращаемое
                                    //значение имеет тип "test"
       cout << "value one = " << summ.value_1 << " value two = " << summ.value_2 << "\n"; 
       return 0;
    }
    
    test func(test first, test second) //принятие двух выбраных тобой элементов
                                       //в данном случае test и test
    {
       test sum;
       sum.value_1 = first.value_1 + second.value_1;
       sum.value_2 = first.value_2 + second.value_2;
       return sum;   //sum являеться структурой "test"
    }
    возвращение через функцию, все как полагается