2015-02-17 2 views
0

Read:Используя символ ** в функции, что мы могли бы таНос память для полукокса *, который передается в ее

и другие вопросы по SO, связанный с этим вопросом и другие на всемирной паутине, поэтому продолжайте читать ...

Так скоро, я не понять, я никогда не alloc как эта память для char *, но я думал, что это может работать:

void _alloc(char *line) 
     *line = malloc(sizeof(char) * BUFSIZE); 

Игнорировать обработчик ошибок в _alloc и main. Главное SEGFAULT в разделе, как это:

main() 
    { 
     char *text, *start; 
     _alloc(text); 
     start = text; 
     // add contents in text briefly 
     *text++ = 'd'; *text = '\0'; // SEGFAULT 
     fprintf(stdout, "%s", start); 
    } 

У меня была картина, что функция _alloc работает что-то вроде этого:

main() 
    { 
    char *text; 
    /// function _alloc: 
    char *tmp = text; 
    *tmp = malloc (sizeof(char) * BUFSIZE); 
    /// end 
    } 

И ... Когда я попробовал это, дайте мне warning: присваивание делает целое число из указателя без литого и SEGF. Моя картина о нем, это:

tmp = text; // tmp point at address of line 
*tmp = malloc(...); // tmp change to what point line... 

И я увидел, что мне нужно в _alloc (символ **), и не могу понять, как он работает с **. Я пытался манипулировать с помощью массива [] [], я это знаю. Но не может получить картину, почему она должна быть символом **? Вот часть ответа:

Здесь line локальная переменная в _alloc. Указатели передаются по значению в C, поэтому получает копию указателя в основном, когда вы делаете _alloc(text); < н.у.к. пользователя ответа (измененный с моим именем переменных) на Scope of malloc used in a function

P.S. я знаю, что проще писать функции, как этот char *_alloc();

+1

Но вы не передаете 'char **' функции '_alloc'. –

+2

'void _alloc (char ** line);' и 'char * text; _alloc (&text); '? – crashmstr

+0

Извините за это, я меняю сейчас. Я изменил имя переменных, потому что это было не так читаемо, и забыть изменить для всех ошибку. – RadijatoR

ответ

2

Давайте рассмотрим простой пример, с междунар.

Предположим, что мы имеем функции:

void foo(int n) 
{ 
    n = 3; 
} 

int main(void) 
{ 
    int number = 5; 
    foo(number); 
} 

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

Именно по этой причине мы используем указатели. Но указатель - это переменная, и это точно то же самое. Посмотрите на этот пример:

void bar(int *n) 
{ 
    *n = 3; 
    int *temp = malloc(sizeof(int)); 
    *temp = 6; 
    n = temp; 
} 

int main(void) 
{ 
    int number = 5; 
    int *number_p = &number; 
    bar(number_p); 
} 

Здесь number = 3 после bar(number_p), потому что мы переходим к bar в адрес нашего целого. Однако сам адрес является копией исходного указателя. Итак, инструкция n = temp; ничего не делает для number_p, так как n - это только локальная переменная.

Вот почему нам нужно использовать указатель на указатель.

на следующем примере, вы можете изменить исходный указатель внутри foo функции:

void foo(int **n) 
{ 
    **n = 3; 
    int *temp = malloc(sizeof(int)); 
    *temp = 6; 
    *n = temp; 
} 

int main(void) 
{ 
    int number = 5; 
    int *number_p = &number; 
    foo(&number_p); //We pass the adress of the pointer number_p 
} 

После foo(&number_p), number является 3, а number_p является указателем на temp, потому что мы смогли изменить адрес себя в foo.

В вашем примере, вы должны изменить указатель в функции _alloc, поэтому подпись должна быть

void _alloc(char **line) 

и указатель должен быть изменен с помощью

*line = malloc(...); 

Кроме того, _alloc должен быть вызванный таким образом

char* s; 
_alloc(&s); 

So rry для моего плохого английского, я сделал все возможное, чтобы быть ясным.

+0

Есть ли утечки памяти, когда void bar (int * n) работает с temp. Temp destroy ?, но делает ли это память, которую выделяет (может считаться утечкой)? – RadijatoR

+0

@RadijatoR Да, есть утечка памяти. 'temp' выделяется в стеке, поэтому он уничтожается в конце' bar', но * temp все еще находится в куче. Во втором примере вам нужно «free (temp)» в конце «bar». В третьем примере вам нужно «free (number_p)» в конце «aain». Мой код был просто иллюстративным. :) – Chostakovitch

+1

Я принимаю, что вы отвечаете, потому что есть что-то, чего я не знал, но у меня еще нет картинки, о char **, вы просто написали «и указатель должен быть изменен с помощью». – RadijatoR

1

Должно быть

void _alloc(char **line){ 
    *line = malloc(sizeof(char) * BUFSIZE); 
} 

использовать так:

/* ... */ 
char *buf; 
_alloc(&buf); 

buf является указателем. Вы получаете указатель на него с &buf, затем передаете его _alloc, который разделяет указатель на указатель, получая значение buf и меняет его, чтобы указать на вновь выделенную память.

C строго передается по значению, поэтому указатели не обрабатываются иначе, чем переменные. То есть, Чтобы понять это, вы могли бы рассмотреть аналогию со следующим кодом:

void changeValue(char *chr){ 
    *chr = 'a'; 
} 

(используется как это :)

/* ... */ 
char buf; 
changeValue(&buf); 
+0

Человек, я спрашиваю, зачем нужен char **, я читаю это то, что вы напишите в прилагаемых ссылках. – RadijatoR

+0

@RadijatoR: обновил мой ответ, посмотрим, поможет ли это вам. – Mints97

+0

Да, это помогает. Но, как вы отправляете свой ответ, вы в _alloc set, * line = malloc ..., так что это ** line mind? почему существует два *? – RadijatoR