Почему именно malloc используется?

Я пытался понять, что такое malloc() и почему он используется. Я понимаю, что malloc для динамического распределения памяти, он нужен, если вы не знаете, сколько памяти вы не хотите создавать. Я занимался этим на практике.

Следующий код объявляет массив указателей на символы, а первый указатель на символ инициализируется с помощью «hello». Это прекрасно работает.

int main()
{


char *strarray[5];
strarray[0]="hello";
printf("%s\n",strarray[0]);
return 0;
}

Но если я попытаюсь использовать функцию strcpy() для копирования строки "hello" в strarray[0] (без malloc()), это вызовет проблему. И он входит в какой-то цикл и не копирует строку. И он отлично работает, если я использую malloc для выделения памяти.

int main()
{

char *strarray[5];
//strarray[0]=(char *)malloc(sizeof(char)*10);
strcpy(strarray[0],"hello");
printf("%s\n",strarray[0]);
return 0;
}

Я хочу знать, в чем разница? Если я могу инициализировать "hello" указателем char, для которого не используется malloc, почему я не могу сделать то же самое с помощью strcpy().


person Ravindra    schedule 13.09.2013    source источник
comment
У вас есть текстовый файл на диске с нужными вам данными в виде массива строк. Одно слово на строку. Когда закончите, ваш массив должен содержать N строк, где N - количество слов в файле... И он должен работать для файла любого размера. Подумайте, как вы не можете не закодировать это с помощью массивов фиксированной длины, а затем спросите себя, для чего malloc() полезна функция выделения памяти.   -  person WhozCraig    schedule 14.09.2013


Ответы (3)


char *strarray[5];

выделит массив из пяти указателей на символы (которые можно интерпретировать как строки).

Что это не будет выделять, так это место в памяти для размещения этих пяти строк. Итак, если вы хотите, чтобы все указатели указывали на разные строки, вам нужно выделить их самостоятельно.

Однако, поскольку это указатели, вам не нужно ничего выделять, если вы этого не хотите. Вот почему ваш первый пример работает. strarray[0]="hello"; заставит первый элемент массива указывать на место, где хранится "hello" строковый литерал (компилятор поместит этот литерал где-то в памяти для вас, поэтому ваш указатель будет указывать на допустимое место в памяти).

Подводя итог, в первом примере ваш указатель указывает на память, уже выделенную и инициализированную с помощью "hello" (компилятор сделал это за вас) - вы не копируете строку, вы просто присваиваете значение указателю. Во втором примере ваш указатель указывает на какое-то неопределенное место, которое вы явно не зарезервировали, но пытаетесь записать в него.

person Nemanja Boric    schedule 13.09.2013
comment
Извините за введение в заблуждение, используя массив из пяти указателей. Вопрос относится даже к указателю на один символ. И я на самом деле использую только один указатель. Я хочу скопировать некоторую строку в этот указатель символа, которому не выделена память с помощью malloc. Если я могу сделать это, просто инициализировав (без malloc), то почему я не могу использовать strcpy без использования malloc(), вот мой вопрос. - person Ravindra; 14.09.2013
comment
@Ravindra на самом деле, вы можете просто игнорировать массив в ответе, так как он сосредоточен на одном указателе. Я добавил последний абзац, который должен иметь смысл. - person Nemanja Boric; 14.09.2013
comment
Вот тут я запутался. Указание на некоторую уже выделенную память и копирование на некоторый указатель, указывающий на неопределенное место! Теперь у меня мало ясности в том, что происходит. Спасибо :) - person Ravindra; 14.09.2013

Это неправильно: char *strarray[5]; Это выделение в стеке 5 указателей char*. Я думаю, вы хотели написать char strarray[6], что создает 6 символов в стеке. Это может вместить «hello» и его неявный NULL-терминатор (NULL-терминатор сообщает функциям C, что строка закончилась).

Написав char strarray[6];, strcpy(strarray, "hello"); в безопасности. Затем вы можете позвонить:

printf("%s\n",strarray);

где я опустил [0]: %s ожидает char*, а не char: strarray[0] относится к типу char.

Вы используете malloc для выделения памяти в куче. Могу ли я предложить вам прочитать Kernighan и Ritchie (язык программирования C) для получения более подробной информации об этом?

person Bathsheba    schedule 13.09.2013
comment
Забудьте о массиве указателей на символы. скажем, у меня есть только один указатель символа, как показано ниже. символ *straray; /*strarray[0]=(char *)malloc(sizeof(char)*10);*/ strcpy(strarray,hello); printf(%s\n,массив); все равно не работает - person Ravindra; 14.09.2013
comment
@Равиндра; Я не могу сказать, где // заканчивается!, но для начала удалите [0] из вашего printf, так как %s ожидает char*, а не char. Смотрите дополнительный текст в моем ответе. - person Bathsheba; 14.09.2013
comment
изменил его. Теперь вы можете получить. Этот комментарий предназначен только для того, чтобы показать разницу в ч/б, если и если нет, то я использую malloc(). - person Ravindra; 14.09.2013
comment
Керниган и Ричи, конечно! Спасибо. - person Ravindra; 14.09.2013
comment
@Равинда удовольствие; прочитайте первую главу, сделайте упражнения, и я с нетерпением жду ваших ответов на так! - person Bathsheba; 14.09.2013

malloc(): выделяет блок размером байт памяти, возвращая указатель на начало блока.

void* malloc (size_t size);  

size_t относится к типу unsigned int.

это необходимо, если вы не знаете, сколько памяти вы не хотите создавать, это неправильно.
вы должны знать, сколько минимальной памяти требуется.

с помощью malloc() вы можете выделить память в run time, а не в compile time.

strarray[0]="hello";   
//here you need not to allocate memory as this is an assignment 

Вам нужно выделить некоторое пространство, прежде чем использовать указатель как destination string в strcpy()

strcpy() Копирует строку C, указанную источником, в массив, указанный местом назначения, включая завершающий нулевой символ (и останавливаясь в этой точке).

размер массива, на который указывает пункт назначения, должен быть достаточно длинным, чтобы содержать ту же строку C, что и источник (включая завершающий нулевой символ), и не должен перекрываться в памяти с источником.

для этого нужно allocate Memory first.

strcpy сам по себе не выделяет память для строки назначения

person Gangadhar    schedule 13.09.2013
comment
Я имел в виду, что вы не знаете, сколько памяти вы хотите создать во время компиляции. - person Ravindra; 14.09.2013
comment
@Ravindra Просто, пожалуйста, попытайтесь понять это. Вам необходимо знать, сколько памяти достаточно для хранения уважаемого контента. В зависимости от того, что вы можете выделить память, она может быть статической (время компиляции) или динамической (время выполнения). Основная цель malloc - когда вы не знаете, сколько членов такого размера требуется. для статического распределения вы не можете увеличивать или уменьшать размер, но вы можете с динамическим. - person Gangadhar; 14.09.2013