我想知道在C ++中何时使用指向指针的指针以及为什么需要指向指针?我知道当我们指向指针时,这意味着我们将变量的内存地址保存到内存中,但我不知道为什么我们需要它?此外,我看过一些例子,总是在创建矩阵时使用指向指针的指针!但是为什么一个矩阵可能需要指向指针?
我想知道在C ++中何时使用指向指针的指针以及为什么需要指向指针?我知道当我们指向指针时,这意味着我们将变量的内存地址保存到内存中,但我不知道为什么我们需要它?此外,我看过一些例子,总是在创建矩阵时使用指向指针的指针!但是为什么一个矩阵可能需要指向指针?
当你想要改变传递给函数的变量的值,并保留该函数之外的更新后的值时,你需要该变量的指针(单指针)作为函数参数。
void modify(int* p)
{
*p = 10;
}
int main()
{
int a = 5;
modify(&a);
cout << a << endl;
}
当你想要改变作为函数参数传递的指针的值时,你需要使用指向指针的指针。
简单来说,当你想在函数调用外保留(或保留更改)内存分配或赋值时,请使用**
。(因此,将这样的函数传递给双指针参数。)
这可能不是一个很好的例子,但会向你展示基本用法:
void safe_free(int** p)
{
free(*p);
*p = 0;
}
int main()
{
int* p = (int*)malloc(sizeof(int));
cout << "p:" << p << endl;
*p = 42;
safe_free(&p);
cout << "p:" << p << endl;
}
void safe_free(int**p) { free(*p); *p = 0; }
- Jarod42int**
传递给safe_free()
,但你正在传递int*
。 - doubleE当我们想要更改指针所指向的地址时,基本上需要使用指向指针的指针。一个非常好的例子就是链表的情况,当我们尝试在开头插入值时,我们会发送一个指向指针的指针到头节点。以下是代码片段:
int main()
{
/* Start with the empty list */
struct node* head = NULL;
/* Use push() to construct below list
1->2->1->3->1 */
push(&head, 1);
push(&head, 2);
.....
....
}
/* Given a reference (pointer to pointer) to the head
of a list and an int, push a new node on the front
of the list. */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
.....
.....
}
这基本上是因为,假设一个指针最初指向一个内存地址0X100
,我们想要将其更改为指向其他位置,比如0X108
。在这种情况下,需要传递指向指针的指针。
你可能之前见过int main()的代码,但你见过这个吗:
int main(int argc, char** argv)
argv确实是一个双指针,它不是真正的双指针,而是一个指向指针数组的指针,每个指针都指向与命令行参数相关的字符数组。
这并不是最好的例子,也许你想要更实用的例子。我会编写一个更好的例子并编辑我的帖子 :)
编辑:
如果您熟悉类和虚函数,则可能也知道具有虚函数的任何类都会自动获得_vftp成员变量。
_vftp成员是一个指向所有虚函数的函数指针列表的指针。它插入在结构的开头处。 如果像下面这样创建了一个新对象:
class myclass
{
public:
//void *_vftp; this is where the _vftp member gets inserted automatically
virtual void vfunc1();
};
void myclass::vfunc1() {printf("yay");}
void main() {
myclass *pMyObject = new myclass();
}
在实例化myclass时,_vftp被添加到对象结构中并且是第一个变量。因为pMyObject是指向内存中此结构的指针,*pMyObject等于_vftp。
因为_vftp是指向虚函数指针数组的指针,*_vftp等于vfunc1(一个函数指针)。
这意味着如果我们对pMyObject进行两次解引用并调用它,我们将调用vfunc1():
typedef (void* (__thiscall* fnVFunc1))(void);
((fnVFunc)**pMyObject)();
虽然双指针并非真正的用途,但这是应用它们的一个典型例子。最常见的双指针使用场景在黑客和逆向工程中,通常需要在内存中查找指针并修改其指向的内容。
int main(int argc, char** argv)
null
。struct
,但这通常需要额外的两行代码。实际上,指向指针的指针允许你直接将指针写入一个将要存在的结构中。假设你想在C++中实例化一个对象...
MyClass * obj = new MyClass();
new
返回指向动态内存中分配的对象的指针。以下方法是错误的:MyClass obj = new MyClass(); // wrong. 'new' returns a pointer.
假设你想要一个对象数组...
MyClass ** objArray = new MyClass*[10];
new MyClass*[10]
给你一个指针数组,而不是对象数组。它也是一个未初始化指针的数组。至少写成 new MyClass*[10]()
来获取一个包含 10 个空指针的数组,或者更好的方法是使用 std::vector<MyClass>
。 - MSalters