2015-09-29 4 views
0

This программа считывает текстовый файл в строковый массив, строко за строкой. Я не могу понять значение двух строк в коде:Невозможно понять значение двух строк в C

char **words = (char **)malloc(sizeof(char*)*lines_allocated); 

... 

words = (char **)realloc(words,sizeof(char*)*new_size); 
... 

Пожалуйста, помогите мне понять их?

+2

Обратитесь к [man page] (http://linux.die.net/man/3/malloc) для 'malloc' и' realloc'. –

ответ

6
char **words = (char **)malloc(sizeof(char*)*lines_allocated); 

Выделить lines_allocated Указатели. Когда вы используете указатель на указатели, вам нужно выделить место для указателей, а для каждого из этих указателей вы выделяете пространство для данных, в данном случае - char *.

words = (char **)realloc(words,sizeof(char*)*new_size); 

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

words указывает на блок, который будет хранить lines_allocated указателей в первый момент, а затем он будет увеличен до new_size при необходимости.

В своем коде вы также строку:

/* Allocate space for the next line */ 
words[i] = malloc(max_line_len); 

Какой будет выделять каждую строку отдельно.


Кроме того, не отбрасывает результат из таНоса:

+0

Если вы компилируете свой код как C++, тогда вам нужно указать результат 'malloc', но если вы пишете C++, вы не должны использовать' malloc' в первую очередь. –

+1

@JohnBode Я знаю, но он помечен как C. –

+0

Отлично! Спасибо! –

3

Первая строка выделяет указатель на указатель на символ. Указатель на что-то в C эквивалентен указателю на массив того же самого, поэтому это эквивалентно тому, что он выделяет указатель на массив указателей на char.

sizeof(char*) - размер указателя, и умножение его на lines_allocated означает, что количество указателей в выделенном массиве будет lines_allocated.

Вторая строка перераспределяет массив указателей так, чтобы теперь они могли содержать указатели new_size вместо lines_allocated указатели. Если new_size больше, новые указатели будут неопределенными и должны быть инициализированы перед использованием.

+0

Большое спасибо! –

3

Первая строка выделяет кусок динамической памяти (создает пространство для массива указателей до char); вторая строка изменяет размер этого фрагмента.

Лучший способ написать обе линии является

char **words = malloc(sizeof *words * lines_allocated); // no cast, operand of sizeof 

char **tmp = realloc(words, sizeof *words * new_size); 
if (tmp) 
    words = tmp; 

В C, вам не нужно отбрасывать результат либо вызова, и это считается плохой практикой, чтобы сделать это. Также обратите внимание на операнд sizeof; если вы когда-либо изменили базовый тип words (от char до wchar_t, например), вам не придется менять вызовы malloc или realloc.

realloc будет возвращать NULL, если он не может расширить буфер, поэтому сначала безопаснее назначить результат временной переменной, иначе вы рискуете потерять ссылку на эту память, то есть вы не сможете получить доступ или освободить его.

+0

Большое спасибо! –

Смежные вопросы