指针在整个函数调用中保持信息

时间:2011-03-25 18:02:05

标签: c

我对函数调用之间的指针发生了什么感到困惑。这不是我所期待的。我有以下情况:

SomeClass *p1= 0, *p2 = 0;
SomeMethod(p1, p2);
printf("P1 total: %d\n", p1->total); // crashes
printf("P2 total: %d\n", p2->total); // crashes

// method someMethod, where the values of the pointers are valid
void SomeMethod(SomeClass *p1, SomeClass *p2)
{
    someMethodThatModifiesThePointers(&p1, &p2);
    printf("P1 total: %d\n", p1->total); // prints valid value
    printf("P2 total: %d\n", p2->total); // prints valid value
};

从我的注释中可以看出,指针的.total属性(整数)在方法内部有效,但在其外部不再有效。为什么会这样?指针不应该失去范围。

确切地说,someMethodThatModifiesThePointers()是opencv的cvExtractSURF。我删除了代码以保持简单。

4 个答案:

答案 0 :(得分:3)

C是一种按值传递的语言。这意味着原始函数中的指针不能通过调用SomeMethod()来改变(顺便说一句,C没有方法)。你在评论的行上崩溃了,因为那时p1p2仍然是空指针。

SomeMethod()内的指针也是如此。如果您将空指针传递给prints valid value,那么您的行号SomeMethod()将因同样的原因而崩溃。你得到你说的输出是不可能的,至少考虑到你所展示的代码。如果你在你的例子中犯了一个错误,你的意思是:

    someMethodThatModifiesThePointers(&p1, &p2);

它可能按照您解释的方式工作 - p1p2然后通过引用传递(也就是说,您通过值传递指针到指针),以及它们值可以在SomeMethod()内有效。但是,代码中的p1p2的原始副本仍然是空指针。

您可以通过执行相同操作来解决问题 - 通过引用将p1p2传递给SomeMethod()

 SomeMethod(&p1, &p2);

此更改将要求您在SomeMethod()中进行一些修改:

void SomeMethod(SomeClass **p1, SomeClass **p2)
{
    someMethodThatModifiesThePointers(p1, p2);
    printf("P1 total: %d\n", (*p1)->total);
    printf("P2 total: %d\n", (*p2)->total);
};

此次通话后,您的热门功能中的p1p2将按照您希望的方式运作。

答案 1 :(得分:0)

发生了什么......

:创建一个指向SomeClass'实例'的指针。

GCC :没问题!完成。

:指定0x0作为该指针的值。也就是说,它指向的'对象'位于存储器中的位置0x0

GCC :好吧,0x0不属于您的程序,但我会随身携带。

:好的。接下来,用我全新的SomeClass实例做一些事情!编译并运行!

操作系统:WOAH WOAH等一下,破坏者。你应该考虑先用malloc()来问我一些记忆。 0x0内存位置属于ME,不属于你。一般保护错误,amigo,享受崩溃。

(顺便说一下,术语'class','instance'等是面向对象的编程术语,它们并不完全属于C.我们通常在这里讨论结构,函数和指针:)

答案 2 :(得分:0)

  

指针的.total属性(整数)在方法内部有效,但在其外部不再有效。为什么会这样?

鉴于它在SomeMethod内打印有效值,打印有效值并在SomeMethod返回时崩溃,我猜两个p1,p2都是按值传递。返回SomeMethod后,p1,p2都是空指针,并且取消引用它会解释崩溃。您需要发布someMethodThatModifiesThePointers(p1, p2);

的代码

答案 3 :(得分:0)

部分原因是您为函数外部和内部的指针选择了相同的名称。试试这个:

SomeClass *p1= 0, *p2 = 0;
SomeMethod(p1, p2);
printf("P1 total: %d\n", p1->total); // crashes
printf("P2 total: %d\n", p2->total); // crashes

// method someMethod, where the values of the pointers are valid
void SomeMethod(SomeClass *p3, SomeClass *p4)
{
    someMethodThatModifiesThePointers(&p3, &p4);
    printf("P3 total: %d\n", p3->total); // prints valid value
    printf("P4 total: %d\n", p4->total); // prints valid value
};

指针p1和p2分别复制到p3和p4,但不是相反。