笔者专注于Android安全领域, 欢迎关注个人的微信公众号《Android安全工程》(可点击进行扫码关注)。个人微信公众号主要围绕 Android 应用的安全防护和逆向分析, 分享各种安全攻防手段、Hook 技术、ARM 汇编等 Android 相关的知识。
char* a 是一个指针,指向一个 char 类型的变量或一段 char 类型的内存空间。在函数的参数列表中,char* a 表示将一个指向 char 类型的指针作为参数传递给函数。
char*& a 是一个指针引用,它指向一个 char 类型的指针。在函数的参数列表中,char*& a 表示将一个指向 char 类型指针的引用作为参数传递给函数。
使用 char* a 作为函数参数时,函数可以修改 a 所指向的内存空间的内容,但不能修改 a 指向的地址;而使用 char*& a 作为函数参数时,函数可以修改 a 指向的地址,进而改变 a 所指向的内存空间的位置和内容。
下面是一个使用 char* a 和 char*& a 的例子:
void foo(char* a)
{
// 修改 a 所指向的内存空间的内容
*a = 'A';
}
void bar(char*& a)
{
// 修改 a 指向的地址
a = new char[2];
// 修改 a 所指向的内存空间的内容
*a = 'B';
}
int main()
{
char c = 'a';
char* ptr = &c;
// 使用 char* a 调用函数 foo
foo(ptr);
// c 的值被修改为 'A'
std::cout << c << std::endl;
char* ptr2 = &c;
// 使用 char*& a 调用函数 bar
bar(ptr2);
// ptr2 指向新的内存空间,其中第一个元素的值为 'B'
std::cout << *ptr2 << std::endl;
// 必须释放动态分配的内存
delete[] ptr2;
return 0;
}
char* a 和 char*& a 区分使用:
-
函数需要修改传入的指针所指向的内存空间的内容,但不需要修改指针本身时,应该使用 char* a。
-
函数需要修改传入的指针指向的内存空间的内容,并且需要在函数外部使用这个指针指向的新内存空间时,可以使用 char*& a。在这种情况下,函数内部应该使用 new 运算符来分配新的内存空间,并且调用者需要负责在适当的时候释放这个内存空间。
-
函数需要修改传入的指针指向的地址时,必须使用 char*& a。在这种情况下,函数可能会改变指针指向的内存空间的位置,这意味着调用者需要注意是否需要重新分配内存空间和释放旧内存空间。
使用 char* a 表示函数不会改变指针本身的值,但可能会修改指针所指向的内存空间的内容。而使用 char*& a 表示函数可能会改变指针本身的值,并且可能会在函数内部分配新的内存空间来存储修改后的内容。
为什么不可以在传入后修改 char* a 所指向的地址呢?
在传递 char* a 时,实际上传递的是指向一段内存空间的地址。函数可以通过这个地址访问并修改这段内存空间的内容,但不能修改这个地址本身。
这是因为在函数调用时,参数是按值传递的。即传递给函数的是指针的副本,而不是指针本身。函数在修改 char* a 所指向的地址时,实际上只是修改了参数的副本,而没有改变原始指针的值。因此,修改 char* a 所指向的地址对原始指针没有影响。
如果需要修改指针本身的值,可以使用 char*& a。这时候,传递的是指向指针的引用,函数可以通过引用来修改指针本身的值,进而改变指针所指向的地址。