我是C编程的新手,很难区分这种语法
ptr = &array[index]
针对这个
*ptr = array[index]
在我值得的示例函数中
void getDevice(Device* device)
这条线就像我期望的那样工作
*device = devices[index];
(取消引用的设备指针现在具有值devices[index]
(
但是这条线会导致段错误
device = &devices[index];
(设备指针有devices[index]
的地址(
我认为两者最终应该具有相同的效果(ptr
指向devices[index]
(。我在这里错过了什么?
实际代码:
void populatePhysicalDevice(VkInstance* gInstance, VkPhysicalDevice* gPhysicalDevice)
{
uint32_t physicalDeviceCount = 0;
vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, VK_NULL_HANDLE);
VkPhysicalDevice physicalDevices[physicalDeviceCount];
vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, physicalDevices);
int bestSuitedPhysicalDeviceLocation = 0;
gPhysicalDevice = &physicalDevices[bestSuitedPhysicalDeviceLocation]; // Causes segfault
*gPhysicalDevice = physicalDevices[bestSuitedPhysicalDeviceLocation]; // Works
}
VkInstance
VkPhysicalDevice
vkEnumeratePhysicalDevices
假设你像这样调用你的函数:
vkInstance instance;
vkPhysicalDevice physicalDevice;
vkCreateInstance(..., &instance);
populatePhysicalDevice(&instance, &physicalDevice);
因此,传递的两个参数的两个值是指向调用方作用域中instance
和physicalDevice
的指针。指针(不是它们指向的值(被复制到populatePhysicalDevice
中的相应变量中:
void populatePhysicalDevice(VkInstance* gInstance, VkPhysicalDevice* gPhysicalDevice)
{
因此,此时,在populatePhysicalDevice()
中,您有两个指针可以随意更改,但不会更改调用方范围内的任何内容。让我们继续:
uint32_t physicalDeviceCount = 0;
vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, VK_NULL_HANDLE);
VkPhysicalDevice physicalDevices[physicalDeviceCount];
vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, physicalDevices);
现在你有一个VKPhysicalDevice
的本地数组,它已被vkEnumeratePhysicalDevices()
填充。现在,您要确保调用方获得最适合的物理设备的副本:
int bestSuitedPhysicalDeviceLocation = 0;
gPhysicalDevice = &physicalDevices[bestSuitedPhysicalDeviceLocation]; // Causes segfault
该行不会执行调用方将看到的任何操作。它只会更改本地变量gPhysicalDevice
以指向本地数组physicalDevices
的开头。当你回来时,所有这些东西都会消失。最终结果是调用方作用域中的[hysicalDevice
尚未初始化。这是分段错误的可能原因。
改为执行此操作时:
*gPhysicalDevice = physicalDevices[bestSuitedPhysicalDeviceLocation]; // Works
您实际上是将physicalDevices[]
的第一个元素的值复制到调用方作用域中的变量physicalDevice
中。
请注意,如果您总是使用第一个物理设备,则不需要创建本地数组,只需执行以下操作:
void populatePhysicalDevice(VkInstance* gInstance, VkPhysicalDevice* gPhysicalDevice)
{
vkEnumeratePhysicalDevices(*gInstance, 1, gPhysicalDevices);
}
但不要忘记,实例实际上可能没有任何可用的物理设备,因此请检查您调用的函数的返回值,并确保它们符合预期!
ptr = &array[index]
设置ptr
指向array[index]
。也就是说,它将array[index]
的地址放入ptr
。
*ptr = array[index]
将*ptr
设置为值array[index]
。也就是说,它获取存储在array[index]
中的值,并将该值放在ptr
指向的位置。它不会改变ptr
.
由于您未提供足够的代码或信息,因此无法确定您报告的段故障的原因。线路本身device = &devices[index];
可能不是原因。