我对函数调用之间的指针发生了什么感到困惑。这不是我所期待的。我有以下情况:
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
。我删除了代码以保持简单。
答案 0 :(得分:3)
C是一种按值传递的语言。这意味着原始函数中的指针不能通过调用SomeMethod()
来改变(顺便说一句,C没有方法)。你在评论的行上崩溃了,因为那时p1
和p2
仍然是空指针。
SomeMethod()
内的指针也是如此。如果您将空指针传递给prints valid value
,那么您的行号SomeMethod()
将因同样的原因而崩溃。你得到你说的输出是不可能的,至少考虑到你所展示的代码。如果你在你的例子中犯了一个错误,你的意思是:
someMethodThatModifiesThePointers(&p1, &p2);
它可能按照您解释的方式工作 - p1
和p2
然后通过引用传递(也就是说,您通过值传递指针到指针),以及它们值可以在SomeMethod()
内有效。但是,代码中的p1
和p2
的原始副本仍然是空指针。
您可以通过执行相同操作来解决问题 - 通过引用将p1
和p2
传递给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);
};
此次通话后,您的热门功能中的p1
和p2
将按照您希望的方式运作。
答案 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,但不是相反。