передача указателя glist в качестве аргумента для отражения изменений в списке не работает

Я хочу передать указатель glist функции, чтобы получить измененное значение в основной функции.

У меня есть код как:

#include <stdio.h>
#include <string.h>
#include <glib.h>

char *col_trim_whitespace(char *str)
{
  char *end;

  // Trim leading space
  while(isspace(*str)) str++;

  if(*str == 0)  // All spaces?
    return str;

  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace(*end)) end--;

  // Write new null terminator
  *(end+1) = 0;

  return str;
}


void line_parser(char *str,GSList* list1)
{
    GSList* list = NULL; 
    char *token, *remstr=NULL ;

    token = strtok_r(str,"\n",&remstr);
    while(token != NULL)
        {
            if(token[0] == ' ')
            {

            token = col_trim_whitespace(token);
            if(strcmp(token,"")==0)
                 {
                     token = strtok_r(NULL, "\n", &remstr);
                     continue;
                  }
            }
            list1 = g_slist_append(list1, token);
            token = strtok_r(NULL,"\n",&remstr);
        }

}

int main()
{

 int *av,i,j,length;
 i=0;

char str[] = " this name of \n the pet is the ffffffffffffffffffffffffffffff\n is \n the \n test\n program";


//GSList *list1 = line_parser(str);
GSList *list1 = NULL;
line_parser(str,list1 );
// printf("The list is now %d items long\n", g_slist_length(list));
 length = g_slist_length(list1);
// printf("length=%d", length);

for(j=0;j<length;j++)
{
    printf("string = %s\n",(char *)g_slist_nth(list1,j)->data);
}

g_slist_free(list1);

return 0;
}

здесь у меня есть имя списка list1 в основной функции, затем я передал list1 в качестве аргумента функции lineparser(), где список изменяется, добавляя некоторые значения. и я хочу вернуть значение функции main(), но без использования оператора return, поскольку я использовал ссылку указателя при передаче аргумента. но значение не возвращается в функцию main(). Как я могу этого добиться?


person user3545251    schedule 04.08.2015    source источник


Ответы (3)


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

void line_parser(char *str,GSList **list1)
{
    ...
    *list1= list;
}

и в основном:

main()
{
    GSList *list1 = NULL;
    line_parser(str, &list1);
    ...
}
person Paul Ogilvie    schedule 04.08.2015

Как оказалось, g_slist_append() возвращает новый начальный указатель списка. Итак, по сути, вы пытаетесь изменить значение list1 из line_parser() и ожидаете, что это значение будет отражено обратно в main().

Ну, это невозможно в нынешнем виде. C использует передачу по значению для передачи параметров функции, поэтому все аргументы, передаваемые функции, являются отдельной локальной копией для вызываемой функции, при этом рассматриваемые как параметры вызываемой функции.

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

Что-то по линии

 void line_parser(char *str,GSList** list1) { //and other usage

а также

 line_parser(str,&list1 );

должен решить вашу проблему.

person Sourav Ghosh    schedule 04.08.2015

Есть много способов сделать это. В одну сторону:

  1. Эта строка GSList *list1 = NULL; создает указатель, а не структуру GSList. Возможно, вы захотите выделить память для списка с помощью malloc и привести его к GSList. Например, GSList list1 = (GSList) malloc(sizeof(GSList));

  2. Тогда в вашу функцию line_parser нам нужно будет передать указатель line_parser(str, &list1)

    Не забудьте free(list1)

Другой способ — создать GSList в стеке. Несмотря на это, мы по-прежнему передаем указатель на line_parser, как упоминалось выше.

person The Brofessor    schedule 04.08.2015