передача двойного указателя в методах c

#c #c #pointers

#c #c #указатели

Вопрос:

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


Передача двойного указателя на функцию в качестве аргумента двойного указателя — работает хорошо

     #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void to_fun(char **dbl_ptr)
    {
      *dbl_ptr = malloc(20);
      strcpy(*dbl_ptr,"cool");
    }
    void main( )
    {

        char **dbl_ptr = calloc ( 2 , sizeof(char *) );
        to_fun ( (dbl_ptr   1) );
        printf("%sn",*(dbl_ptr   1) );
    }
  

Передача двойного указателя на функцию в качестве аргумента с одним указателем — ошибка seg

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>

void to_fun(char *dbl_ptr)
{
  dbl_ptr = malloc(20);
  strcpy(dbl_ptr,"defnitely not cool");
}
void main( )
{

    char **dbl_ptr = calloc ( 2 , sizeof(char *) );
    to_fun ( *(dbl_ptr   1) );
    printf("%sn",*(dbl_ptr   1) );
}
  

Передача двойного указателя на функцию в качестве аргумента с одним указателем — работает хорошо

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>

void to_fun(char *dbl_ptr)
{
  printf("%sn",dbl_ptr );
}
void main( )
{

    char **dbl_ptr = calloc ( 2 , sizeof(char *) );
    *(dbl_ptr   1) = "cool";
    to_fun ( *(dbl_ptr   1) );
}
  

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

Я знаю, как указатели и разыменование работают в глубине, но все же это раздражает. Любой объяснит, почему.

Комментарии:

1. Что calloc ( 2 , 1 ); предполагается делать? Особенно, почему 2 и 1 ?

2. В чем разница между первым и вторым образцом кода, кроме разных строк?

3. ой, мой плохой, исправлен сейчас

4. C — это другой язык, отличный от C, и соображения для такого рода вещей в C отличаются от C. Выберите один .

5. Ваши второй и третий примеры не «передают [a] двойной указатель на функцию в качестве аргумента с одним указателем». Они передают один указатель (a char * ) на функцию, которая, в свою очередь, ожидает аргумент именно этого типа.

Ответ №1:

Первый блок кода работает, потому что вы передаете указатель, а затем разыменовываете этот указатель, чтобы изменить то, на что указывает указатель (т. Е. Блок памяти, выделенный в main ).

В случае второго блока кода вы изменяете параметр функции dbl_ptr . Изменения параметров функции не отражаются в вызывающей функции, поскольку все параметры передаются по значению.

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

Кроме того, вы передаете не a char ** во вторую и третью функции, а a char * .

Вы также не выделяете достаточно памяти main . Вы выделяете 2 байта, но вам нужно место для 2 char * :

 char **dbl_ptr = calloc ( 2 , sizeof(char *) );
  

Ответ №2:

Когда вы хотите изменить переменную внутри функции, а переменная находится за пределами области действия функции, вы передаете указатель на переменную:

 void f(double *x) {
  *x = 12;
}

void main() {
  double z;
  f(amp;z);
  printf("%f", z);
}
  

Когда ваша переменная является указателем, вам нужен указатель на указатель:

 void f(double **x) {
  *x = malloc(...);
}

void main() {
  double *z;
  f(amp;z);
  printf("%f", z[1]);
}
  

Комментарии:

1. ДА. Вот так просто.