2009-12-14 2 views
0

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

struct message 
{ 
void* data; 
}msgG; 

Какой бы лучшим способом для извлечения данных (то есть Получить сообщение доступным для fUN1 в коде): 1- с помощью глобальной переменной 2- Использование двойных указателей (указатель на указатель)

//Note: msgG is the global variable 

void fun2(struct message **ptr) 
{ 
    **ptr = msgCreate(); // msgCreate returns a type struct message; 
    msgG = msgCreate(); 

} 

void fun1() 
{ 
.... 
..... 

struct message *ptr; 
ptr = malloc(sizeof(struct message)); 

fun2(&ptr); 
... 
} 

Теперь мы сообщение, хранящуюся в msgG и PTR? Какой из них лучше? Использование глобальной переменной или доступ к указателю, поскольку один из них выделен в куче, а другой в bss (не уверен в этом)? Есть ли другой способ справиться с такой ситуацией?

+0

Не могли бы вы дать немного больше контекста? Я не уверен, что я достаточно разбираюсь в ситуации, чтобы дать свое мнение. – Juan

+0

@juan: msgCreate() обычно используется как recv() из программы netwrking. Я разговариваю с abt обрабатывая полученное сообщение. – tomkaith13

ответ

3

Не использовать глобальную переменную. То, что вы пытаетесь сделать может быть сделано таким образом:

void fun2(struct message *ptr) 
{ 
    *ptr = msgCreate(); 
} 

void fun1() 
{ 
    struct message *m = malloc(sizeof *m); 
    if (m == NULL) { 
     /* error handling */ 
    } 
    fun2(m); 
} 

Если struct message большой, рассматривать не имеющие функцию, возвращающую такой struct. В большинстве случаев более эффективно возвращать указатель на некоторую память, чем возвращать большую автоматическую переменную из функции.

0

Это может быть так просто, как это:

struct message 
{ 
    void* data; 
} msgG; 


void fun2(struct message the_msg) 
{ 
    /* access the_msg.data */ 
} 

void fun1() 
{ 
    struct message *ptr; 
    ptr = malloc(sizeof(struct message)); 
    ptr->data = ... /* initialize it to something */ 

    fun2(*ptr); 
} 

Но этот путь, fun2 не сможет манипулировать the_msg, потому что он принял копию структуры по значению. Он сможет манипулировать материалом, на который указывает указатель data внутри the_msg, потому что это указатель.

Если вы хотите, чтобы управлять содержимым the_msg себя, например, нацелить на data указатель, fun2 должен принимать указатель на message (двойной указатель ненужный для этого).

И глобальная переменная почти всегда является плохим решением. Не используйте его.

+0

@eliben: Итак, когда мы точно используем двойные указатели. Раньше я думал, что он используется в таких ситуациях. – tomkaith13

+0

@ tomkaith13: двойные указатели используются, когда * нужно изменить указатель *, а не его содержимое. В одном случае вы хотите, чтобы функция создавала новый указатель на что-то, и вы передаете свой собственный указатель в качестве аргумента. –

+0

@ tomkaith13: больше для двойных указателей: http://stackoverflow.com/questions/758673/uses-for-multiple-levels-of-pointer-dereferences, а также http://stackoverflow.com/questions/897366/ how-do-pointer-to-pointers-work-in-c –

1

Это хорошая практика, чтобы избежать глобализации.

Примечание: если вы пытаетесь кода объектно-ориентированного в C, посмотрите на эту документацию ooc.pdf

Смежные вопросы