Jak korzystać z realloc w C [duplicate]

Nov 25 2020

Próbuję ponownie przydzielić pamięć za pomocą funkcji realloc, widziałem, że musisz wcześniej użyć malloc, ale nie rozumiem, czy MUSISZ go użyć, ponieważ powiedzmy, że tworzę następujący ciąg:

char string[] =  "fun";

czy funkcja realokacji zadziała, jeśli spróbuję dodać więcej miejsca?

to prowadzi mnie do mojego pytania, próbuję po prostu dodać jedną literę na końcu łańcucha, powiedzmy „p”, ale z jakiegoś powodu program miażdży wiersz ponownego przydzielania za każdym razem, gdy go uruchamiam.

Oto mój pełny kod:

int main()
{
char string[] =  "fun" ;
str_func(string);
printf("%s", string);
return 0;
} 

void str_func(char* str)
{
str = (char*)realloc(str, strlen(str) + 2);
strcat(str, "p");
}

Próbowałem też utworzyć wskaźnik na „łańcuch znaków” i wysłać wskaźnik, co skutkuje tym samym.

Odpowiedzi

1 Lundin Nov 25 2020 at 19:32

czy funkcja realokacji zadziała, jeśli spróbuję dodać więcej miejsca?

Nie, ponieważ ta tablica nie jest przydzielona na stercie - w twoim przypadku jest bardzo prawdopodobne, że jest przydzielona na stosie i nie można jej zmienić. Mówiąc najprościej: reallocnie rozpoznaje wskaźnika i nie wie, co z nim zrobić, ale mimo to próbuje coś zrobić, stąd awaria.

Możesz wywołać tylko reallocwskaźnik, który został poprzednio przekazany malloc, lub wskaźnik pusty. Tak właśnie działają te funkcje.

Aby uzyskać szczegółowe informacje, zobacz Co jest przydzielane na stosie i stercie? .

1 Useless Nov 25 2020 at 19:58

Widziałem, że musisz wcześniej użyć malloc, ale nie rozumiem, czy MUSISZ go używać

Jeśli musisz użyć, malloczanim realloccoś będziesz mógł , to z definicji musisz tylko reallocrzeczy pierwotnie przydzielone malloc.

Próbujesz znaleźć jakąś przestrzeń między „potrzebą” a „koniecznością”, która nie istnieje.

... z jakiegoś powodu program zawiesza się przy ponownym przydzielaniu

Powiedziałeś już, że wiesz, że musisz użyć malloc. Wtedy nie używałeś malloci pytasz, dlaczego to jest problem. Możesz przynajmniej spróbować zrobić to, co „wiesz”, że musisz zrobić, aby zobaczyć, czy to rozwiąże problem.

Program powinien prawdopodobnie wyglądać

int main()
{
  /* array is an automatic local variable. It wasn't dynamically allocated
     in the first place, so can't be dynamically re-allocated either.
     You cannot (and don't need to) free it either, it just goes out of scope
     like any other automatic variable.
  */
  char array[] = "fun";

  /* you need to use malloc (or one of the other dynamic allocation functions)
     before you can realloc, as you said yourself */
  char *dynamic = malloc(1+strlen(array));
  memcpy(dynamic, array, 1+strlen(array));

  /* realloc can move your data, so you must use the returned address */
  dynamic = str_func(dynamic);
  printf("old:'%s', new:'%s'\n", array, dynamic);

  /* not really essential since the program is about to exit anyway */
  free(dynamic);
} 

char* str_func(char* str)
{
  char* newstr = realloc(str, strlen(str) + 2);
  if (newstr) {
    strcat(newstr, "p");
    return newstr;
  } else {
    /* we failed to make str larger, but it is still there and should be freed */
    return str;
  }
}

Twój pierwotny stan nie jest całkiem poprawny: w rzeczywistości wskaźnik został przekazany do realloc

... musi być wcześniej przydzielane przez malloc(), calloc()albo realloc()i jeszcze uwolniony z wezwaniem do uwolnienia lub realloc

[LUB] Jeśli ptr ma wartość NULL, zachowanie jest takie samo jak wywołanie malloc(new_size).

paxdiablo Nov 25 2020 at 19:31

reallocFunkcja działa tylko z rzeczy, które zostały pierwotnie utworzone z niewielką grupą przydziału funkcji (takich jak malloc, calloclub reallocsiebie) lub wskaźnik NULL. Ponieważ stringnie jest to żadna z tych rzeczy, twój kod nie jest dobrze zdefiniowany.