Załóżmy, że mam wskaźnik przydzielony do przechowywania 4096 bajtów. Jak można zwolnić ostatnie 1024 bajty w C? A co z C++? Co jeśli zamiast tego chciałem zwolnić najpierw 1024 bajtów i zachować resztę (w obu językach)? Co powiesz na dealokację od środka (wydaje mi się, że to wymagałoby podzielenia go na dwa wskaźniki, przed i po rozdzielonym regionie).C i C++: Uwolnienie CZĘŚĆ przydzielonego wskaźnika
Odpowiedz
Jeśli masz n
bajtów malloc
przyklejając pamięci, można realloc
m
bajtów (gdzie m
< n
), a zatem wyrzucić ostatnie n-m
bajtów.
Aby wyrzucić z początku, można malloc
nowy, mniejszy bufor i memcpy
bajtów, które chcesz, a następnie free
oryginał. Ta ostatnia opcja jest również dostępna przy użyciu C++ new
i delete
. Może również emulować pierwszy przypadek realloc
.
"malloc/memcpy/free" to jak realloc może być zaimplementowany wewnętrznie. – Roddy
Zgadzam się, że realloc zazwyczaj zwróci (tę samą) pierwszą część, ale czy jest to oficjalny wymóg ponownego wysłania? Myślę, że tutaj mogą być implementacje, które mogą przenieść dane do nowego miejsca. –
Wyobraź sobie inteligentny schemat realokacji, w którym śledzony jest historyczny wzór alokacji ... jeśli były ostatnio żądania alokacji dla 4096 bajtów, lepiej byłoby przenieść blok kurczący się gdzie indziej, aby zwolnić ten blok 4K. W takim przypadku adres zmieni się. Realloc zwraca wskaźnik do nowego obszaru pamięci, więc programista powinien z niego korzystać. Czy to się zmieni, czy nie. – xcramps
Możesz go skrócić za pomocą realloc(). Nie sądzę, żeby reszta była możliwa.
Możesz użyć realloc(), aby pozornie zmniejszyć pamięć. Zauważ, że w przypadku niektórych implementacji takie wywołanie faktycznie nie działa. Nie możesz uwolnić pierwszego fragmentu bloku i zachować ostatniego bitu.
Jeśli potrzebujesz tej funkcji, powinieneś rozważyć użycie bardziej złożonej struktury danych. Tablica nie jest właściwą odpowiedzią na każdy problem programistyczny.
Wdrażam system pamięci, więc szukam jak niski poziom dostępu, jak tylko mogę, a jednocześnie pozostać przenośny. – Imagist
http://en.wikipedia.org/wiki/New_(C%2B%2B)
STRESZCZENIE: W przeciwieństwie do realloc C za to nie jest możliwe bezpośrednie realokacji pamięci przydzielonej z new []. Aby przedłużyć lub zmniejszyć rozmiar bloku, jeden musi przydzielić nowy blok o odpowiednim rozmiarze , skopiować na starą pamięć, a usunąć stary blok. Biblioteka standardu C++ zapewnia dynamiczną tablicę, w której może zostać rozszerzony lub zmniejszony w swoim szablonie std :: vector o wartości .
Nie próbuj odgadnąć zarządzania pamięcią. To zwykle mądrzejszy niż ty ;-)
Jedyną rzeczą, jaką można osiągnąć to pierwszy scenariusz do „zwalnianie” ostatniej 1K
char * foo = malloc(4096);
foo = realloc(foo, 4096-1024);
Jednak nawet w tym przypadku, nie ma gwarancji, że „foo "pozostaną niezmienione. Twój cały 4K może zostać zwolniony, a realloc() może przenieść twoją pamięć gdzie indziej, unieważniając w ten sposób wszelkie wskazówki, które możesz posiadać.
Dotyczy to zarówno C i C++ - jednak, korzystanie z malloc() w C++ jest zły zapachy kodu, a większość ludzi będzie oczekiwać na użycie new() przydzielić pamięci masowej. A pamięć przydzielona za pomocą new() nie może być ponownie przydzielona(), a przynajmniej nie w przenośny sposób.Wektory STL byłyby znacznie lepszym podejściem w C++
Nie masz "wskaźnika przydzielonego do przechowywania 4096 bajtów", masz wskaźnik do przydzielonego bloku 4096 bajtów.
Jeśli twój blok został przydzielony z malloc()
, realloc()
pozwoli ci zmniejszyć lub zwiększyć rozmiar bloku. Jednak adres początkowy bloku nie musi być taki sam.
Nie można zmienić adresu początkowego bloku pamięci d, który jest tak naprawdę o to pyta drugi scenariusz. Nie ma również sposobu na podzielenie bloku d z malloc
.
To ograniczenie malloc
/calloc
/realloc
/free
API - i implementacje mogą polegać na tych ograniczeń (na przykład prowadzenie księgowości informacji o przydziale bezpośrednio przed adresu początkowego, która stałaby przesuwając adres startowy trudny)
teraz malloc
nie jest jedynym podzielnik tam. - Twoja platforma lub biblioteki może dostarczyć pozostałych, czy można pisać własne (które pobiera pamięć z systemu poprzez malloc
, mmap
, VirtualAlloc
lub niektóre inny mechanizm), a następnie przekazuje go programowi w dowolny sposób, jaki sobie życzysz.
Dla C++, jeśli przydzielisz pamięć z std::malloc
, powyższe informacje dotyczą. Jeśli używasz new
i delete
, alokujesz pamięć i konstruujesz obiekty, a więc zmiana rozmiaru przydzielonego bloku nie ma sensu - obiekty w C++ mają stały rozmiar.
- 1. przekazywanie przydzielonego wskaźnika przed przydzieleniem
- 2. Usuwanie wskaźnika w C++
- 3. Tablica wskaźnika C
- 4. Kiedy używać wskaźnika do wskaźnika w C++?
- 5. Różnice w niepełnych regułach tablicy wskaźnika między C i C++
- 6. ISO C++ zabrania porównywania wskaźnika i liczby całkowitej [-feprissive] | [C++]
- 7. Specjalizacja szablonu C++ dla wskaźnika?
- 8. sizeof() część struktury C - sortowanie
- 9. C# zawiera część ciągu znaków
- 10. C++ Deklaracja wskaźnika po stępce
- 11. C++ 11 Inteligentne użycie wskaźnika
- 12. C++: Błąd uszkodzenia dziwnego wskaźnika
- 13. Nieoczekiwane zachowanie wskaźnika w C++
- 14. C++ Konstruktor kopiowania + obiekt wskaźnika
- 15. Anomalia wskaźnika C, proszę wytłumaczyć
- 16. C 64-bitowe wyrównywanie wskaźnika
- 17. C++, błąd wyjątku wskaźnika funkcji
- 18. C Przyporządkowanie wskaźnika w funkcji
- 19. Prawidłowe idiom za uwolnienie repr (C) konstrukcjom użyciu Opadowej cechę
- 20. C++ Przekazywanie wskaźnika do funkcji (Howto) + manipulacja wskaźnikiem C++
- 21. Przekazywanie wskaźnika C za pomocą interfejsu API Python/C
- 22. przekonwertować odwołanie do reprezentacji wskaźnika w C++
- 23. Funkcja nie zmienia przekazanego wskaźnika C++
- 24. C++: Jak zapobiec specjalizacji wskaźnika przez szablon?
- 25. C++: Głębokie kopiowanie wskaźnika klasy podstawowej
- 26. Go odpowiednik pustego wskaźnika w C
- 27. Jak wyciąć część obrazu w języku C#
- 28. Wybierz część ze środka listy w C#
- 29. C++ 11 lambdas do wskaźnika funkcji
- 30. C typedef od wskaźnika do struktury
Nie jestem tego pewien, ale użycie "fałszywego" wskaźnika o odpowiednim rozmiarze, usunięcie lub uwolnienie tego, którego potrzebujesz, powinno załatwić sprawę, potrzebujesz co najmniej 2 wskaźników. – claf
@ claferri. To jest niezdefiniowane zachowanie. Możesz tylko zwolnić() wskaźniki zwrócone z malloc/realloc - w przeciwnym razie, w jaki sposób free() wie, ile za darmo? – Roddy
@roddy: oups masz rację :) – claf