Выделение памяти для языка char * C - PullRequest
7 голосов
/ 04 июня 2010

Это правильный способ выделения памяти для символа *.

char* sides ="5";

char* tempSides;

tempSides = (char*)malloc(strlen(inSides) * sizeof(char));

Ответы [ 7 ]

15 голосов
/ 04 июня 2010

Почти. Строки заканчиваются NULL, поэтому вы, вероятно, захотите выделить дополнительный байт для хранения байта NULL. То есть, хотя sides имеет длину 1 символ, в действительности это 2 байта: {5, '\0'}.

Так было бы:

tempSides = (char *)malloc((strlen(sides)+1)*sizeof(char));

и если вы хотите скопировать его в:

strcpy(tempSides, sides);
9 голосов
/ 04 июня 2010

Обратите внимание:

  1. Строки заканчиваются нулем (\ 0), и strlen () не считается;
  2. По определению sizeof (char) равен 1 (байт), поэтому он не требуется;
  3. Если вы используете компилятор C (не C ++), нет необходимости приводить его к char *;

Так это будет:

char *tempSides = malloc(strlen(inSides) + 1);

Тем не менее, если вы хотите дублировать содержимое inSides, вы можете использовать strdup, например ::

char *tempSides = strdup(inSides);
if (tempSides != NULL) {
    // do whatever you want...
    free(tempSides);
}
3 голосов
/ 04 июня 2010

Как уже указывалось, вы пропустили выделение места для завершающего символа NUL. Но я также хотел бы отметить несколько других вещей, которые могут сделать ваш код более лаконичным.

По определению, sizeof(char) всегда равно 1, поэтому вы можете сократить строку распределения до:

tempSides = (char*)malloc(strlen(inSides) + 1);

Другое дело, что похоже, что вы делаете для дублирования строки. Для этого есть встроенная функция:

tempSides = strdup(inSides);

Это обрабатывает получение длины, выделение правильного количества байтов и копирование данных.

1 голос
/ 04 июня 2010

Нет, не совсем. Как уже отмечали другие, вам нужно выделить место для терминатора 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;
}
1 голос
/ 04 июня 2010

Есть проблема с этим. tempSides будет указывать на неинициализированный блок памяти размером 1. Если вы намереваетесь скопировать строку сторон в tempSides, вам потребуется выделить размер на один байт больше, чтобы удерживать нулевой терминатор для строки. Значение, возвращаемое функцией strlen (), не включает в себя нулевой терминатор в конце строки.

0 голосов
/ 16 ноября 2016

Правильный способ выделения динамической памяти 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;
0 голосов
/ 04 июня 2010

Умножение количества элементов на sizeof(char) является вопросом личных предпочтений, поскольку sizeof(char) всегда равно 1. Однако, если вы делаете это для согласованности, лучше использовать тип указателя получателя, чтобы определить размер элемента, а не указывать введите явно. И не разыгрывайте результат malloc

tempSides = malloc(strlen(inSides) * sizeof *tempSides);

Конечно, при работе со строками с нулем в конце вы должны помнить, чтобы выделить дополнительное место для символа завершающего нуля. Невозможно сказать, намерено ли вы сделать tempSides строкой с нулевым символом в этом случае, поэтому я не могу сказать, нужна ли она вам.

...