存储指针值

时间:2011-01-11 17:05:29

标签: c pointers memory-management

据我所知,当一个指针传递给一个函数时,它只是一个真实指针的副本。现在,我想要更改真正的指针,而不必从函数返回指针。例如:

int *ptr;

void allocateMemory(int *pointer)
{
     pointer = malloc(sizeof(int));
}

allocateMemory(ptr);

另一件事,就是如何将内存分配给2个或更多维数组?不是通过下标,而是通过指针算术。是这样的:

int array[2][3];
array[2][1] = 10;

与:

相同
int **array;
*(*(array+2)+1) = 10

另外,为什么我必须传入指向函数的指针的内存地址,而不是实际的指针本身。例如:

int * a;

为什么不:

allocateMemory(*a) 

allocateMemory(a)

我知道我总是要这样做,但我真的不明白为什么。请向我解释。

最后一点是,在这样的指针中:

int *a;

是包含实际值的内存地址,还是指针的内存地址?我一直认为a是它指向的实际值的内存地址,但我不确定。顺便说一句,打印这样的指针时这样:

printf("Is this address of integer it is pointing to?%p\n",a);
printf("Is this address of the pointer itself?%p\n",&a);

5 个答案:

答案 0 :(得分:10)

我会尝试一次解决这些问题:

  1.   

    现在,我想要更改真实指针,而不必从函数返回指针。

    您需要再使用一层间接:

    int *ptr;
    
    void allocateMemory(int **pointer)
    {
        *pointer = malloc(sizeof(int));
    }
    
    allocateMemory(&ptr);
    
    来自Here is a good explanation

  2. comp.lang.c FAQ

  3.   

    另一件事,就是如何将内存分配给2个或更多维数组呢?

    第一个维度的一个分配,然后是另一个维度的分配循环:

    int **x = malloc(sizeof(int *) * 2);
    for (i = 0; i < 2; i++)
        x[i] = malloc(sizeof(int) * 3);
    

    同样,here链接到comp.lang.c FAQ的确切问题。

  4.   

    这是:

    int array[2][3];
    array[2][1] = 10;
    
         

    与:

    相同
    int **array;
    *(*(array+2)+1) = 10
    

    绝对不是。指针和数组不同。但是,您可以有时互换使用它们。查看these questions。{/ p>

  5. 中的comp.lang.c FAQ
  6.   

    另外,为什么我必须传入指向函数的指针的内存地址,而不是实际的指针本身呢?

         

    为什么不:

    allocateMemory(*a) 
    

    这是两件事--C没有传递引用,除非你通过传递指针自己实现它,在这种情况下还因为a尚未初始化 - 如果你要解除引用它,你会导致未定义的行为。此问题与this one中的comp.lang.c FAQ类似。

  7. int *a;
    
         

    是包含实际值的内存地址,还是指针的内存地址?

    这个问题对我来说没有意义,但我会试着解释一下。 a(正确初始化时 - 此处的示例不是)是一个地址(指针本身)。 *a是指向的对象 - 在这种情况下,它将是int

  8.   

    顺便说一下,打印这样的指针时这样:

    printf("Is this address of integer it is pointing to?%p\n",a);
    printf("Is this address of the pointer itself?%p\n",&a);
    

    在两种情况下都正确。

答案 1 :(得分:1)

要回答第一个问题,您需要将指针传递给指针。 (int**

要回答第二个问题,您可以使用该语法访问现有数组中的位置 但是,嵌套数组(int[][])与指针指针(int**

不同

回答你的第三个问题:

a会传递变量a的值,这是一个内存地址 写*a将值指向传递给变量,该变量是实际值,而不是内存地址。

如果函数采用指针,则意味着它需要一个地址,而不是一个值 因此,您需要传递a,而不是*a 如果a是指向指针(int**)的指针,则会传递*a,而不是**a

答案 2 :(得分:0)

你的第一个问题:

你可以传递指针的地址:

void allocateMemory(int **pointer) {
    *pointer = malloc(sizeof(int));
}

int *ptr;
allocateMemory(&ptr);

或者您可以返回指针值:

int *allocateMemory() {
    return malloc(sizeof(int));
}

int *ptr = mallocateMemory();

答案 3 :(得分:0)

我觉得你对指针究竟是什么感到有些困惑 指针只是变量,其值表示内存中的地址。因此,当我们说int *p是指向整数的指针时,这意味着p是一个变量,它包含一个数字,即int的内存地址。
如果希望函数分配整数缓冲区并更改变量p中的值,则该函数需要知道存储在内存p中的位置。所以你必须给它一个指向p的指针(即p的内存地址),它本身就是一个指向整数的指针,所以函数需要的是指向指向一个整数的指针。整数(即函数应该存储一个数字的内存地址,而这又是函数分配的整数的内存地址),所以

void allocateIntBuffer(int **pp)
{
    // by doing "*pp = whatever" you're telling the compiler to store
    // "whatever" not in the pp variable but in the memory address that
    // the pp variable is holding.
    *pp = malloc(...);
}

// call it like
int *p;
allocateIntBuffer(&p);

我认为你的问题的关键是理解指针变量并没有什么特别之处。指针是一个变量,与其他任何变量一样,只是存储在该变量中的值用于表示内存中的位置。

答案 4 :(得分:0)

请注意,返回指针或强制调用者将指针移出void *临时变量,这是唯一方式,您可以使用void *键入以允许您的函数使用不同的指针类型。 char **int **等不能转换为void **。因此,我建议您不要尝试做什么,而是使用需要更新指针的函数的返回值,除非您的设计功能仅适用于特定类型。特别是,尝试更改接口以传递指针到指针类型的简单malloc包装器本身就会被破坏。