此函数如何更改堆栈上声明的变量的值?
How does this function change the value of a variable declared on the stack?
我目前正在学习一些使用 Vulkan API 的编程。这就是该 API 中的典型调用方式。如果您不熟悉它,请不要太担心它的含义。
pickPhysicalDevices(){
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
}
基本上,vkEnumeratePhysicalDevices 函数返回系统可用的物理设备计数,并将该值放入 deviceCount 中。我的问题是,既然我在pickPhysicalDevices((函数堆栈上声明了deviceCount,为什么vkEnumeratePhysicalDevices不会导致分段错误?
简短的回答是因为pickPhysicalDevices
明确允许vkEnumeratePhysicalDevices
通过提供其指针来修改变量deviceCount
。
C++提供了多种方法,让一个函数修改另一个函数上下文中的值 - 通过传递指针或传递引用。
传递的内容(指针或引用(取决于调用的函数的声明。如果函数采用uint32_t&
(带 & 符号(,则传递一个不带 & 符号的变量,并且该函数会收到一个引用。如果函数采用uint32_t*
(带星号(,则使用地址运算符&
传递指向变量的指针。
进入接受指针的函数后,可以编写*pointer = ...
为指针指向的变量分配新值。另一方面,引用不需要星号。
在一个简单的程序中尝试这两种方法:
void by_ref(uint32_t& ref) {
ref = 123; // No asterisk
}
void by_ptr(uint32_t* ptr) {
*ptr = 456; // Note the asterisk
}
int main() {
uint32_t a, b;
by_ref(a);
by_ptr(&b);
cout << a << " " << b << endl;
}
不能返回局部变量的地址,因为在函数返回后,其局部变量超出了范围。不过,将其作为参数传递是可以的,因为父函数的变量在子函数的持续时间内都在范围内。
param deviceCount 的地址被推入 vkEnumeratePhysicalDevices 的堆栈帧中。
因此,当您在 vkEnumeratePhysical Devices 中更改 deviceCount 的值时,它实际上是在更改 vkEnumeratePhysicalDevices 自己的堆栈帧。
- 在将变量声明为引用时,堆在释放后使用
- 静态变量声明和定义
- 在变量声明中使用 for 循环
- 向量索引变量声明(size_t 或 std::vector<DATATYPE>::size_type)
- C++ 类型类的变量声明不命名类型?
- 将本地 OpenCV Mat 变量声明为静态以防止重新分配
- std::enable_if 更改成员 *变量* 声明/类型
- 在C++中,变量声明左侧的大括号是什么意思?
- 将变量声明为全局变量,然后声明为局部变量 -Shadowing-
- 命名空间内C++变量声明
- 将静态全局变量声明为内联有什么意义吗?
- 如何将一个变量声明为另一个变量的值
- 如何将迭代器变量声明为私有成员变量
- 没有变量声明为函数,但错误:二进制表达式的操作数无效
- 有没有人有书面证据来保证函数中参数的定义方式与普通变量声明相同?
- ClangTool 如何获取变量声明中模板参数的位置?
- 标准与显式自动推导变量声明
- C 静态变量声明怪异链接器错误
- 如何为数组成员变量声明 getter/setter
- 可视C++变量声明