Вы можете использовать указатели.
В частности, вы используете указатель на адрес и используя стандартные вызовы функций библиотеки c, вы просите операционную систему расширить кучу, чтобы вы могли хранить то, что вам нужно.
Теперь он может отказаться, с которым вам придется обращаться.
Следующий вопрос - как вы запрашиваете 2D-массив? Ну, вы запрашиваете массив указателей, а затем расширяете каждый указатель.
В качестве примера рассмотрит следующее:
int i = 0;
char** words;
words = malloc((num_words)*sizeof(char*));
if (words == NULL)
{
/* we have a problem */
printf("Error: out of memory.\n");
return;
}
for (i=0; i<num_words; i++)
{
words[i] = malloc((word_size+1)*sizeof(char));
if (words[i] == NULL)
{
/* problem */
break;
}
}
if (i != num_words)
{
/* it didn't allocate */
}
Это получает вас двумерный массив, где каждый элемент words[i]
может иметь различный размер, определяемый во время выполнения, так же, как количество слов.
Вы должны free()
все результирующей памяти с помощью цикла по массиву, когда вы закончите с этим:
for (i = 0; i < num_words; i++)
{
free(words[i]);
}
free(words);
Если вы этого не сделаете, вы будете создавать утечку памяти.
Вы также можете использовать calloc
. Разница заключается в вызове конвенции и эффекте - calloc
инициализирует всю память до 0
, тогда как malloc
- нет.
Если вам нужно изменить размер во время выполнения, используйте realloc
.
Кроме того, важно, следить за word_size + 1, которые я использовал. Строки в C ноль-завершены, и это требует дополнительного символа, который вам нужно учитывать. Чтобы я помню это, я обычно устанавливаю размер переменной word_size
независимо от размера слова (длина строки, как я ожидаю) и явно оставляю +1 в malloc для нуля. Тогда я знаю, что выделенный буфер может принимать строку из word_size
символов. Не делать этого тоже хорошо - я просто делаю это, потому что я хочу явно объяснить нуль очевидным образом.
Существует также недостаток этого подхода - Я явно видел это как отправленную ошибку в последнее время. Заметьте, я написал (word_size+1)*sizeof(type)
- представьте, однако, что я написал word_size*sizeof(type)+1
. Для sizeof(type)=1
это одно и то же, но Windows использует wchar_t
очень часто - и в этом случае вы зарезервируете один байт за свой последний нуль, а не на два, и они являются элементами с нулевым оканчиванием типа type
, а не одиночными нулевыми байтами. Это означает, что вы будете набирать обороты при чтении и записи.
Приложение: сделайте это независимо от того, что вам нравится, просто следите за этими нулевыми терминаторами, если вы собираетесь передать буфер тому, что полагается на них.
Ваша терминология кажется немного запутанной здесь. Я ожидал бы, что num_words == 2 подразумевает, что должны быть два слова и слова [0], а слова [1] содержат их. Затем вы должны malloc (num_words * sizeof (char *)). –
@ Вы правы. Я думаю, я имел в виду это в отношении +1 для учета нулевого терминатора. Исправление :) –
Откуда возникает переменная 'num_words'? –