此函数如何更改在堆栈上声明的变量的值?

时间:2018-06-22 01:54:47

标签: c++ memory segmentation-fault memory-address vulkan

我目前正在学习有关Vulkan API的一些编程知识。这就是该API中典型调用的方式。如果您不熟悉它的含义,不必太担心。

pickPhysicalDevices(){
    uint32_t deviceCount = 0;
    vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
}

基本上,vkEnumeratePhysicalDevices函数返回系统可用的物理设备的计数,并将该值放入deviceCount中。我的问题是,因为我在pickPhysicalDevices()函数堆栈上声明了deviceCount,为什么vkEnumeratePhysicalDevices不会引起分段错误?

3 个答案:

答案 0 :(得分:3)

简短的回答是因为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;
}

答案 1 :(得分:0)

参数deviceCount的地址被推入vkEnumeratePhysicalDevices的堆栈框架。

因此,当您在vkEnumeratePhysicalDevices中更改deviceCount的值时,实际上是在更改vkEnumeratePhysicalDevices自己的堆栈框架。

答案 2 :(得分:0)

您不能返回局部变量的地址,因为函数返回后,其局部变量将超出范围。不过,将其作为 parameter 传递是可以的,因为父函数的变量在子函数的作用范围内。