Това ли е правилният начин за разпределяне на памет към char*.
char* sides ="5";
char* tempSides;
tempSides = (char*)malloc(strlen(inSides) * sizeof(char));
Това ли е правилният начин за разпределяне на памет към char*.
char* sides ="5";
char* tempSides;
tempSides = (char*)malloc(strlen(inSides) * sizeof(char));
почти. Низовете завършват с NULL, така че вероятно искате да отделите допълнителен байт за съхраняване на байта NULL. Тоест, въпреки че sides
е дълъг 1 символ, той наистина е 2 байта: {5
,'\0'
}.
Така че би било:
tempSides = (char *)malloc((strlen(sides)+1)*sizeof(char));
и ако искате да го копирате в:
strcpy(tempSides, sides);
sizeof(char)
не е необходимо; sizeof(char)
се определя като 1.
- person caf; 04.06.2010
strcpy
- person R Samuel Klatchko; 04.06.2010
sizeof *tempSides
би било най-добре, ако се притеснявате да преминете към wchar_t
по-късно.
- person jamesdlin; 04.06.2010
nul
е ASCII псевдоним за нулевия знак; терминът 'nul' не се появява никъде в стандарта C.
- person dreamlax; 04.06.2010
\0
след въвеждането, и strlen()
, и strcpy
ще се провалят по същия начин като предложената от вас проверка.
- person MSalters; 04.06.2010
malloc
.
- person jweyrich; 04.06.2010
strncpy
вместо strcpy
. В този случай знаем, че буферът е достатъчно голям, така че strcpy
е ОК. Предпочитам обаче да избягвам strcpy
във ВСИЧКИ случаи. Разходите са толкова малки, че е малко вероятно да видите реална разлика в производителността.
- person daotoad; 05.06.2010
Забележи, че:
char *
;Така че това би било:
char *tempSides = malloc(strlen(inSides) + 1);
И все пак, ако искате да дублирате съдържанието на inSides
, можете да използвате strdup
, напр.:
char *tempSides = strdup(inSides);
if (tempSides != NULL) {
// do whatever you want...
free(tempSides);
}
Както беше посочено, вие сте пропуснали да разпределите място за завършващия NUL символ. Но също така исках да посоча няколко други неща, които могат да направят кода ви по-сбит.
По дефиниция sizeof(char)
винаги е 1, така че можете да съкратите своя ред за разпределение до:
tempSides = (char*)malloc(strlen(inSides) + 1);
Друго нещо е, че това изглежда, че правите, за да дублирате низа. Има вградена функция, която прави това вместо вас:
tempSides = strdup(inSides);
Това обработва получаването на дължината, разпределянето на правилния брой байтове и копирането на данните.
Има проблем с това. tempSides ще посочи неинициализиран блок памет с размер 1. Ако възнамерявате да копирате страничния низ в tempSides, тогава ще трябва да разпределите размер с един байт по-дълъг, за да задържите нулевия терминатор за низа. Стойността, върната от strlen(), не включва нулевия терминатор в края на низа.
Не наистина. Както други вече отбелязаха, трябва да отделите място за терминатора NUL.
В допълнение, обикновено не трябва да кастирате връщането от malloc
. Може да прикрие грешка, при която сте забравили да #include
правилната заглавка. Умножаването по sizeof(char)
също е безсмислено, тъй като стандартите (както C, така и C++) определят sizeof(char)
винаги да бъде 1.
И накрая, всяко обаждане до malloc
трябва да включва тест на резултата. Бих увил всичко във функция:
char *dupe_string(char const *string) {
char *temp;
if (NULL!=(temp=malloc(strlen(string)+1)))
strcpy(temp, string);
return temp;
}
Умножаването на броя на елементите по sizeof(char)
е въпрос на лично предпочитание, тъй като sizeof(char)
винаги е 1. Въпреки това, ако правите това за последователност, по-добре използвайте типа на указателя на получателя, за да определите размера на елемента, вместо изрично да указвате типа. И не предавайте резултата от malloc
tempSides = malloc(strlen(inSides) * sizeof *tempSides);
Разбира се, когато работите с низове, завършващи с нула, трябва да запомните да отделите допълнително място за завършващия символ нула. Няма начин да се каже дали намерението ви е да направите tempSides
низ, завършващ с нула в този случай, така че не мога да кажа дали имате нужда от него.
strlen
... Ако той използва своя собствена strlen, тогава наистина не искам да бъда програмистът по поддръжката след него. ;)
- person Secure; 04.06.2010
inSides
е завършен с нула. В кода няма индикация, че tempSides
също трябва да завършва с нула.
- person AnT; 04.06.2010
Правилният начин за разпределяне на динамична памет към tempSides
е както е показано по-долу:
char* sides ="5";
char* tempSides;
tempSides = (char*)malloc((strlen(sides) + 1) * sizeof(char));
char*
съхранява данни от низ, подобно на char[]
. Низовете са null (\0)
прекратени. Така че допълнителен един байт трябва да бъде разпределен за null
символно съхранение.
Динамично разпределеният блок памет трябва да бъде освободен с помощта на free()
, след като употребата му приключи. Ако не бъде освободен, ще се случи изтичане на памет.
free(tempSides);
Когато паметта бъде освободена, трябва да се присвои NULL
, за да се предотврати това да бъде висящ указател.
tempSides = NULL;