malloc вътрешна функция / извикване по референция / valgrind

Не съм много професионалист в C и затова получавам проблем с valgrind.

Искам да прочета въвеждане от командния ред.

Ако опитам по този начин, работи добре.

//call the function
char *command = getUserInput();


//function
char *getUserInput()
{ 
  char *buffer = NULL;
  char *temp = NULL;
  unsigned int count = 0;
  unsigned int lenght = 10;
  char character = 0;

  buffer = malloc((lenght+1)*sizeof(char));
  if(buffer == NULL)
  {
    // printf(ERROR_OUT_OF_MEM);
    // return EXIT_OUT_OF_MEM;
  }

  while((character = getchar()) != '\n')
  {
    if(count == lenght)
    {
      lenght += 10;
      temp = realloc(buffer,lenght*sizeof(char));
      if(temp != NULL)
        {
          buffer = temp;
        }
      else
        {
          free (buffer);
          // printf(ERROR_OUT_OF_MEM);
          // return EXIT_OUT_OF_MEM; 
        }
    }

    buffer[count] = character;
    count++;

  }
  buffer[count] = '\0';

  return buffer;
}

Но не мога да получа върната стойност за грешка.

Ако го опитам по начина, по който се обаждам по препратка, получавам някаква грешка на valgrind, която не разбирам. И знам, че в това извикване на примерна функция не изисквам върнатата стойност.

//call function
char *command = NULL;
getUserInput(command);

//function
int getUserInput(char *name)
{ 
  char *temp = NULL;
  unsigned int count = 0;
  unsigned int lenght = 10;
  char character = 0;

  name = malloc((lenght+1)*sizeof(char));
  checkMemory(name);

  while((character = getchar()) != '\n')
  {
    if(count == lenght)
    {
      lenght += 10;
      temp = realloc(name,lenght*sizeof(char));
      if(temp != NULL)
        {
          name = temp;
        }
      else
        {
          free (name);
          printf(ERROR_OUT_OF_MEMORY_MESSAGE);
          return ERROR_OUT_OF_MEMORY; 
        }
    }

    name[count] = character;
    count++;

  }
  name[count] = '\0';

  return RETURN_SUCCESS;
}

Commandhandler-Line 1199 е if (strcmp(command, "thing_to_compare") == 0)

Валгринд:

==23886== Use of uninitialised value of size 4
==23886==    at 0x40256BB: strcmp (mc_replace_strmem.c:426)
==23886==    by 0x8049B39: commandHandler (assa.c:1199)
==23886==    by 0x8049D6C: main (assa.c:1295)
==23886==  Uninitialised value was created by a stack allocation
==23886==    at 0x8049B00: commandHandler (assa.c:1189)
==23886== 
==23886== Invalid read of size 1
==23886==    at 0x40256BB: strcmp (mc_replace_strmem.c:426)
==23886==    by 0x8049B39: commandHandler (assa.c:1199)
==23886==    by 0x8049D6C: main (assa.c:1295)
==23886==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Изобщо не знам къде е проблема.

поздрави Филип


person phiob    schedule 24.01.2014    source източник
comment
Казва, че проблемът е във функция, наречена commandHandler. Как очаквате да кажем нещо разумно за тази функция, ако не ни я покажете?   -  person Jens Gustedt    schedule 24.01.2014
comment
Съжалявам, забравих командатаHandler. Редактирах публикацията.   -  person phiob    schedule 24.01.2014
comment
command е NULL, това е грешката. Няма нищо подобно на извикване чрез препратка в C. Вие изпратихте стойността на командата на функцията и ако тя се промени там, това е локално копие, което се променя, а не оригиналната променлива.   -  person Marian    schedule 24.01.2014


Отговори (1)


getUserInput няма начин да промени стойността на command, тъй като всички функции се предават по стойност в C. Следователно, когато стигнете до всичките си strcmp функции, вие дереферирате този NULL указател, причинявайки всякакви лоши неща.

Ако искате getUserInput да може да променя стойността на command, трябва да предадете адреса на command на функцията (което означава, че след това функцията трябва да приеме аргумент char**).

person tabstop    schedule 24.01.2014
comment
Благодаря, значи сега трябва да предам стойността по този начин? getUserInput(&command); и във функция int getUserInput(char **name)? Нещото, което не разбирам, е как да получа достъп до name вътре във функцията. Промяна на всеки name на *name? Ако направя това, получавам Segmentation Fault. - person phiob; 24.01.2014
comment
Когато стигнете до присвояването на отделни знаци, ще трябва да направите нещо като (*name)[count], за да запазите реда на операциите в съответствие. - person tabstop; 24.01.2014