Jak korzystać z realloc w C [duplicate]
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
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: realloc
nie 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 realloc
wskaź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? .
Widziałem, że musisz wcześniej użyć malloc, ale nie rozumiem, czy MUSISZ go używać
Jeśli musisz użyć, malloc
zanim realloc
coś będziesz mógł , to z definicji musisz tylko realloc
rzeczy 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ś malloc
i 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()
alborealloc()
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)
.
realloc
Funkcja działa tylko z rzeczy, które zostały pierwotnie utworzone z niewielką grupą przydziału funkcji (takich jak malloc
, calloc
lub realloc
siebie) lub wskaźnik NULL. Ponieważ string
nie jest to żadna z tych rzeczy, twój kod nie jest dobrze zdefiniowany.