2013-08-15 10 views
7

Miałem problemy naprawić kod dzisiaj, potem natknąć się coś podobnego do:przydzielić pamięci dla struktury ze wskaźnikiem znaków w C

typedef struct { 
int a; 
int b; 
int c; 
int d; 
char* word; 
} mystruct; 

int main(int argc, char **argv){ 

    mystruct* structptr = malloc(sizeof(mystruct)); 
    if (structptr==NULL) { 
     printf("ERROR!") 
     ... 
    } 
    ... 
    free(structptr); 

    return 0; 
} 

kod został dając dużą ilością błędów pamięci ze względu na fakt, , że char* word jest ciągiem o zmiennej długości, a malloc nie alokował dla niego wystarczającej ilości pamięci. W rzeczywistości przydzielono tylko 20 Bytes dla całego struct. Czy istnieje sposób obejścia tego problemu, bez przekształcania char* w coś takiego jak char word[50]?

+0

Widziałeś, że masz komentarz, ale potem go usunąłeś. Zmień swoje pytanie, podając dodatkowe informacje lub prześlij drugie pytanie. Istnieją metody radzenia sobie z wektorem 'char', który zmienia swoją długość. – JackCColeman

+0

Dodałem komentarz, a następnie znalazłem odpowiedź w komentarzach poniżej. Uważam, że ustalony rozmiar bufora jest w rzeczywistości najlepszym rozwiązaniem, ponieważ słowo będzie reprezentować nazwę, a nazwy nie powinny być tak długie jak powieści;). Dzięki za pomoc.Byłem naprawdę ciekawy, jak przydzielić pamięć dla zmiennych ciągów, dlatego zapytałem. Ale i tak zamierzałem przejść na tablice o stałej długości. –

+0

w tych dniach przestrzeń (czyli pamięć RAM) jest obfita, więc w większości przypadków definiowanie tablicy znaków o wielkości 1024 nie spowoduje problemu. Bufory we/wy są rutynowo znacznie większe. – JackCColeman

Odpowiedz

16

Przydzielasz tylko pamięć dla samej struktury. Obejmuje to wskaźnik do char, który jest tylko 4 bajty w systemie 32-bitowym, ponieważ jest częścią struktury. NIE zawiera pamięci dla nieznanej długości ciągu znaków, więc jeśli chcesz mieć ciąg znaków, musisz również ręcznie przydzielić pamięć dla tego łańcucha. Jeśli właśnie kopiujesz ciąg, możesz użyć strdup(), który przydziela i kopiuje ciąg. Musisz jednak jeszcze uwolnić pamięć.

mystruct* structptr = malloc(sizeof(mystruct)); 
structptr->word = malloc(mystringlength+1); 

.... 

free(structptr->word); 
free(structptr); 

Jeśli nie chcesz przydzielić pamięci dla napisu siebie, jedynym wyborem jest zadeklarować stała długość tablicy w swojej struktury. Wtedy będzie częścią struktury i będzie ją zawierał. Jeśli ma to zastosowanie, zależy to od twojego projektu.

+0

@ H2CO3, czy chcesz dopracować to, co uważasz za błędne? – Devolus

+1

@ H2CO3, Nie sądzę, aby Devolus docenił twoją perspektywę. – JackCColeman

+1

@JackCColeman, tym bardziej, że nie jest zbyt konstruktywne, aby critzize bez żadnej informacji, co byłoby nie tak. – Devolus

3

Dodaj drugą malloc niezależnie od długości (N) trzeba za word

mystruct* structptr = malloc(sizeof(mystruct)); 

    structptr->word = malloc(sizeof(char) * N); 
-1

Zastosowanie word=malloc(128);

ten przeznaczy 128 bajtów do varible słowem

1

Podczas przydzielania pamięci dla structptr, wskaźnik word w nie ma prawidłowej pamięci do wskazania. Więc albo malloc kawałek pamięci dla word, albo uczynić word wskazać inną postać.

4

jak można przeczytać here trzeba przeznaczyć char * oddzielnie:

mystruct* structptr = malloc(sizeof(mystruct)); 
structptr->word = malloc(sizeof(WhatSizeYouWant)); 
0

malloc zewnętrzna struktura będzie przydzielać pamięć tylko 1 bajt wskazanych przez *word ponieważ jest to „char *” typ. Jeśli chcesz przeznaczyć więcej niż 1 bajt pamięci wskazywanego przez word, są 2 opcje:

  1. Jak to, co pan powiedział, zadeklarować ją jako char word[50] zamiast `char *”
  2. malloc/calloc (ja osobiście preferuj calloc, oszczędzając ci kłopotów z zeromemory, co jest bardzo ważne ..) zewnętrzna struktura, następnie malloc/calloc wewnętrzna word również. Pamiętaj, aby w tym przypadku dwukrotnie dzwonić pod numer free.