Próbuję napisać program, który czyta serię ciągów z pliku tekstowego i zapisuje je w tablicy łańcuchów, dynamicznie alokując pamięć dla każdego elementu. Mój plan polegał na przechowywaniu każdego ciągu znaków w tablicy przy użyciu wskaźnika, a następnie zwiększeniu rozmiaru tablicy, gdy więcej było czytanych. Mam problem z zrozumieniem, dlaczego mój testowy kod nie działa. Czy to jest praktyczny pomysł?Dynamiczna alokacja pamięci dla tablic wskaźnika
Odpowiedz
W języku C ciąg znaków to char*
. Tablica dynamiczna typu T
jest reprezentowana jako wskaźnik do T
, więc dla char*
byłaby to char**
, a nie tylko char*
w sposób, w jaki ją zadeklarowałeś.
Kompilator bez wątpienia wydał ostrzeżenia na ten temat. Uważaj na te ostrzeżenia, bardzo często pomagają ci zrozumieć, co robić.
Oto jak można rozpocząć testowanie:
char **aPtr;
int len = 1; // Start with 1 string
aPtr = malloc(sizeof(char*) * len); // Do not cast malloc in C
aPtr[0] = "This is a test";
printf("%s",aPtr[0]); // This should work now.
Aby zweryfikować (proszę o wyrozumiałość, jestem nowicjuszem =]), jeśli chciałbyś mieć dynamiczną tablicę wskaźników do zwrócenia uwagi (np. W razie potrzeby w aplikacji, gdzie może być konieczne przechowywanie ciągów znaków o zmiennej liczbie np. Od czytając plik tekstowy bez znajomości jego długości lub zbierając dane wejściowe użytkownika o nieokreślonej długości), potrzebna jest dynamiczna tablica Char *, więc potrzebujesz Char **. Znak char może wskazywać na różne znaki, które mogą być początkowym adresem różnych ciągów znaków. –
po co jest "len = 1"? Wygląda na to, że 'To jest test' miałby 14 znaków, z których każdy jest bajtem ... ale ten kod nie wspomina o 14, ani też nie ulega awarii po uruchomieniu. – nmz787
@ nmz787 Zwróć uwagę na typ 'aPtr', to podwójna wskazówka, więc reprezentuje tablicę wskaźników char. Wskaźnik char jest następnie ustawiony na element zero; w tym kodzie nie ma miejsca na kopiowanie ciągów. – dasblinkenlight
char * aPtr;
jest jako wskaźnik do znaku, do którego przydzielona pamięć do przechowywania dokładnie 1
charakter.
Doing
aPrt[0] = "test";
adresowania pamięci dla tej jeden znaków i spróbuj zapisać adres dosłownym "test"
do niego. To się nie uda, ponieważ ten adres jest bardziej szeroki niż znak.
Poprawkę do kodu oznaczałoby przydzielenie pamięci dla wskaźnika do znaku.
char ** aPtr = malloc(sizeof(char *));
aPtr[0] = "test";
printf("%s", aPtr[0]);
są bardziej elegancki i bardziej nad solidnego podejścia byłoby przeznaczyć te same (jak również dodanie obowiązkowe sprawdzanie błędów), wykonując:
char ** aPtr = malloc(sizeof *aPtr);
if (NULL == aPtr)
{
perror("malloc() failed");
exit(EXIT_FAILURE);
}
...
char *str; //single pointer
Z tego można przechowywać jeden strunowy.
Aby zapisać array of strings
jest potrzebne two dimensional character array
albo array of character pointers
albo double pointer
char str[10][50]; //two dimensional character array
Jeśli zadeklarujesz tak nie trzeba przydzielić pamięci jako ta jest statyczna deklaracja
char *str[10]; //array of pointers
Tutaj trzeba przydzielić pamięci dla każdego wskaźnika
pętlę poprzez tablicę przydzielić pamięci dla każdego wskaźnika
for(i=0;i<10;i++)
str[i]=malloc(SIZE);
char **str; //double pointer
Tutaj trzeba przydzielić pamięci dla Ilość wskaźniki, a następnie przydzielić pamięć dla każdego wskaźnika.
str=malloc(sizeof(char *)*10);
I następnie pętli tablicy przydzielić pamięci dla każdego wskaźnika
for(i=0;i<10;i++)
str[i]=malloc(SIZE);
robisz to całkowicie błędne. Poprawna wersja twojego kodu powinna wyglądać następująco:
int main()
{
char *aPtr;
aPtr =(char*)malloc(20*sizeof(char));
aPtr ="This is a test";
printf("%s",aPtr);
}
Możesz użyć tablicy wskaźnikowej. jeśli chcesz przechowywać wiele ciągów. Tak, wiem, że używanie pętli for będzie łatwe. Ale staram się wyjaśnić w prosty sposób, nawet początkujący mogą to zrozumieć.
int main()
{
char *aPtr[10];
aPtr[0] =(char*)malloc(20*sizeof(char));
aPtr[0] ="This is a test";
aPtr[1] =(char*)malloc(20*sizeof(char));
aPtr[1] ="This is a test2";
printf("%s\n%s\n",aPtr[0],aPtr[1]);
}
Twój pierwszy przykład przecieka pamięć, czyli 20 bajtów. Robiąc "aPtr =" To jest test ";" tracisz odwołanie do tego, co zwróciło 'malloc()'. Pamięć ta nigdy nie była używana i nigdy nie będzie używana w czasie trwania programu. – alk
'sizeof (char)' to '1' to definicja. Przesyłanie wyniku 'malloc/calloc/realloc' nie jest konieczne w C ani zalecane: http://stackoverflow.com/a/605858/694576 – alk
Dziękuję wszystkim, którzy odpowiedzieli, że była to świetna pomoc – user2826534
- 1. Dynamiczna alokacja pamięci szeregowej
- 2. Alokacja dynamiczna z podziałem pamięci GPU 2D
- 3. Statyczna i dynamiczna alokacja pamięci obiektów w C++
- 4. do std :: function i std :: bind czy dynamiczna alokacja pamięci?
- 5. Alokacja pamięci dla tablicy char
- 6. Pula obiektów a alokacja dynamiczna
- 7. Alokacja pamięci w STL C++
- 8. Alokacja pamięci dla macierzy w C
- 9. Alokacja pamięci w C++
- 10. Alokacja pamięci w C
- 11. Alokacja pamięci zespołu
- 12. Jak działa alokacja pamięci stałej CUDA?
- 13. Alokacja pamięci char * i char []
- 14. Alokacja pamięci wewnątrz jądra CUDA
- 15. Alokacja pamięci zoptymalizowana przez kompilatory
- 16. Alokacja pamięci do obiektów typu String?
- 17. Plik odwzorowany w pamięci dla numpy tablic
- 18. CUDA: Alokacja pamięci urządzenia pakującego w C++
- 19. Alokacja pamięci podczas uruchamiania systemu Linux?
- 20. Dynamiczna analiza kodu dla C++
- 21. Usuń wskaźnik do wskaźnika (jako tablicy tablic)
- 22. Valgrind mówi "alokacja stosów", mówię "alokacja sterty"
- 23. Alokacja ciągu w języku C++
- 24. Windows vs. alokacja pamięci Linux/wydajność konstruktora std :: list
- 25. Dynamiczna ikona powiadomienia dla Androida
- 26. Dynamiczna maksymalna szerokość dla tekstu
- 27. 17.8 Alokacja sterty MiB dla prostego projektu "Hello World"?
- 28. Używanie pamięci Python z numpy tablic
- 29. tablicę wskaźników na char tablic
- 30. auto_ptr dla tablic
To nie działa, ponieważ 'malloc' przestrzeni dla pojedynczego znaku, a następnie spróbować przypisać cały ciąg do' char' wpisany lwartości. –
Zalecane uwagi: [Kiedy należy używać malloc w C i kiedy nie mam?] (Http://stackoverflow.com/a/1963812/2455888). – haccks