Kiedy używać malloc dla wskaźników znakowych

Koncentruję się szczególnie na tym, kiedy używać malloc na wskaźnikach znaków

char *ptr;
ptr = "something";
...code...
...code...
ptr = "something else";
Czy malloc byłby w porządku na coś tak trywialnego jak to? Jeśli tak, to dlaczego? Jeśli nie, to kiedy jest konieczne dla wskaźników znakowych?
Author: Bastien Léonard, 2009-11-24

5 answers

Jak wskazywali inni, nie musisz używać malloc tylko do zrobienia:

const char *foo = "bar";

Powodem tego jest właśnie to, że *foo jest wskaźnikiem - podczas inicjalizacji foo nie tworzysz kopii ciągu znaków, tylko wskaźnik do miejsca, w którym "bar" mieszka w sekcji danych Twojego pliku wykonywalnego. Możesz kopiować ten wskaźnik tak często, jak chcesz, ale pamiętaj, że zawsze wskazuje on na tę samą pojedynczą instancję tego ciągu.

Kiedy należy stosować malloc? Normalnie używasz strdup(), aby skopiować łańcuch, który obsługuje malloc w tle. np.

const char *foo = "bar";
char *bar = strdup(foo); /* now contains a new copy of "bar" */
printf("%s\n", bar);     /* prints "bar" */
free(bar);               /* frees memory created by strdup */

Teraz wreszcie przejdziemy do sprawy, w której możesz chcieć malloc, jeśli używasz sprintf() lub bezpieczniej snprintf(), która tworzy / formatuje nowy ciąg znaków.

char *foo = malloc(sizeof(char) * 1024);        /* buffer for 1024 chars */
snprintf(foo, 1024, "%s - %s\n", "foo", "bar"); /* puts "foo - bar\n" in foo */
printf(foo);                                    /* prints "foo - bar" */
free(foo);                                      /* frees mem from malloc */
 32
Author: scotchi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 15:44:24

malloc służy do przydzielania pamięci w wolnym sklepie. Jeśli masz ciąg znaków, którego nie chcesz modyfikować, to jest ok:

char *literal = "foo";

Jednak, jeśli chcesz być w stanie go zmodyfikować, użyj go jako bufora do przechowywania linii wejściowej i tak dalej, użyj malloc:

char *buf = (char*) malloc(BUFSIZE); /* define BUFSIZE before */
// ...
free(buf);
 11
Author: dirkgently,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-14 11:54:49

Użyj malloc(), gdy nie znasz ilości pamięci potrzebnej podczas kompilacji. W przypadku, gdy masz ciągi tylko do odczytu, możesz użyć const char* str = "something";. Zauważ, że łańcuch jest najprawdopodobniej przechowywany w pamięci tylko do odczytu i nie będziesz mógł go modyfikować. Z drugiej strony, jeśli znasz ciąg znaków w czasie kompilatora, możesz zrobić coś w stylu: char str[10]; strcpy(str, "Something"); tutaj pamięć jest przydzielana ze stosu i będziesz mógł zmodyfikować str. Trzeci przypadek to przydzielanie za pomocą malloc. Lets say you nie znam długości ciągu podczas kompilacji. Wtedy możesz zrobić char* str = malloc(requiredMem); strcpy(str, "Something"); free(str);

 5
Author: Naveen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-24 08:40:39

Malloc dla pojedynczych znaków lub liczb całkowitych i calloc dla tablic dynamicznych. ie pointer = ((int *)malloc(sizeof(int)) == NULL) , możesz wykonywać arytmetykę w nawiasach malloc, ale nie powinieneś, ponieważ powinieneś użyć calloc, która ma definicję void calloc(count, size), co oznacza, ile elementów chcesz przechowywać liczbę ie i rozmiar danych ie int , char itd.

 2
Author: transby dogarite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-05 14:00:22

Za każdym razem, gdy rozmiar łańcucha jest nieokreślony w czasie kompilacji, musisz przydzielić pamięć za pomocą malloc (lub jakiejś metody equiviallent). W Twoim przypadku znasz rozmiar twoich łańcuchów w czasie kompilacji (sizeof ("coś") i sizeof ("coś innego")).

 1
Author: Lucas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-24 10:06:04