2

在这段代码中,依赖于gdbp从分配0x6020100x0 何时更改NULL,(如我所料)

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

int main()
{
    int a = 10;

                        // gdb output
    int *p = (int *) malloc(sizeof(int));   // p = (int *) 0x602010
    p = NULL;               // p = (int *) 0x0
    p = &a;                 // p = p = (int *) 0x7fffffffe15c           

    return 0;
}

但是,当在 inp之外更改时,我想它不会更改为,我不知道为什么:main()task()0x0

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

void tast(int *p);

void task(int *p)
{

/*
 before
 (gdb) p p
 $1 = (int *) 0x7fffffffe15c         (same as variable a)
 (gdb) p &p
 $2 = (int **) 0x7fffffffe128
*/

    p = NULL;

/*
 after
 (gdb) p p
 $3 = (int *) 0x7fffffffe15c        no change?
 (gdb) p &p
 $4 = (int **) 0x7fffffffe128
*/    
}

int main()
{
    int a = 10;

                        // gdb output
    int *p = (int *) malloc(sizeof(int));   // p = (int *) 0x602010
    p = NULL;               // p = (int *) 0x0
    p = &a;                 // p = p = (int *) 0x7fffffffe15c

    // it is possible to change what p points to 
    // after calling task()?
    task(p);

    // p will be NULL?          

    return 0;
}

为什么 p 在 task() 中没有变为 0x0?

4

4 回答 4

2

指针是一个值,就像一个int. 可以这样想:如果你传入一个intintask()并在函数内部改变它task会期望它改变吗?不,因为变量是按值传递的。

当您调用时,task您将值的副本(在本例中为指针)传递给函数。您要做的是更改指针的值,这意味着您需要一个指向存储值的位置的指针。这是一个指向指针的指针,int **.

反而:

void task(int **p)
{
   *p = NULL;
}

task(&p);

传递的位置p *

另一个例子,这次使用int,这可能会更清楚。

void makeTen(int *valuePointer)
{
    // Change the variable that valuePointer is pointing to. 
    *valuePointer = 10; 
}

void demoFunction()
{
    int x = 5;

    // x == 5

    // Call this with a pointer to the variable X.
    // We are passing the memory address of the variable x.
    makeTen(&x);

    // x == 10

}

如果您了解这一点,请更改int为 be int *,您将了解您原来的问题。

于 2012-08-22T15:50:34.240 回答
1

在第一个片段中,当您将 NULL 分配给 malloc 的指针时,您正在泄漏内存。

在第二个片段中,您通过指针的值传递指针。所以这些变化不会反映在 main.js 中。这说明了问题。

于 2012-08-22T15:51:44.823 回答
0

如果您p == NULL在传递指针后期望在 main 中,则需要将指针传递给该指针。例如

void task(int** p)
{
  *p = NULL;
}

并通过

task(&p);

此外,您应该注意此代码泄漏。你应该在调用free(p)之前设置。p = NULLmalloc

于 2012-08-22T15:51:05.583 回答
0

因为你弄错了指针地址和它指向的对象。

void task(int *p)
{
    p = NULL; 
}

此函数将采用指向 int 的指针,因此,您可以修改存储在其他位置的 int 值。不过,您的 int 值的变量地址是按值传递的。这意味着,地址存储在本地。将“NuLL”分配给局部变量不是您想要的。

如果你把它改成这样:

void task(int **p)
{
    *p = NULL; 
}

您将获取指向 int 的指针的指针。现在地址也被指向了,你可以从你的代码中改变它。必须通过引用传递指向 int 的指针(这是您的情况)。

于 2012-08-22T15:51:17.180 回答