在C语言中使用VULKAN VkEnum-foo-bar函数时如何避免VLA和malloc?

大虫

C 语言中的 Vulkan 编程似乎不可避免地使用 malloc 或VLA,请看以下示例:

    uint32_t physicalDeviceNumber = 0;
    vkEnumeratePhysicalDevices(*instance, &physicalDeviceNumber, NULL);

    VkPhysicalDevice physicalDevice[physicalDeviceNumber];
    vkEnumeratePhysicalDevices(*instance, &physicalDeviceNumber, physicalDevice);

这段代码只是列举了物理设备,因为我不知道 GPU 的确切数量,所以我打电话vkEnumeratePhysicalDevices来获取这个数字。然后再次调用它来实际初始化它们。在第二个函数调用中,第三个参数VkPhysicalDevice *pPhysicalDevices必须是一个已定义的数组。它的长度必须等于 GPU 的数量,否则物理设备初始化将不完整。请参阅此处的规范

问题来了,上面的代码使用了C 语言中的一个危险特性,称为VLA,或“可变长度数组”。此功能允许在堆栈上创建一个内存块,其大小为运行时生成的数字。他们绝对应该避免。这个博客告诉我们原因。

另一种解决方案是使用 malloc 来解决这个问题,我稍微更改了代码:

    uint32_t physicalDeviceNumber = 0;
    vkEnumeratePhysicalDevices(*instance, &physicalDeviceNumber, NULL);

    VkPhysicalDevice *physicalDevice = (VkPhysicalDevice *)malloc(physicalDeviceNumber * sizeof(VkPhysicalDevice));
    vkEnumeratePhysicalDevices(*instance, &physicalDeviceNumber, physicalDevice);

当然,这会破坏程序。TypeVkPhysicalDevice实际上是一个指针,它的真正类型是struct VkPhysicalDevice_T *,它指向一大块大小未知的内存。此外,在 vulkan 编程中使用 malloc 被认为是一个习惯。请参阅此处的讨论

所以我很困惑。这个简单的函数不能安全地用于初始化我的 GPU,除非我知道我的电脑有多少 GPU。我不是 C 方面的专家,但我认为应该有比这些代码更安全的解决方案。如果您知道如何,请提供简单的 C 代码并解释原因。

ps:C++ 代码不是我想要的,我知道std::vector可以解决这个问题,但我不会使用 C++。

用户253751

malloc如果你没有犯错,你可以使用

您不是在分配 VkPhysicalDevices 数组,而是在分配指向VkPhysicalDevices的指针数组并且您将数组的地址传递给 vkEnumeratePhysicalDevices,而不是指向数组的指针的地址(这会导致它在不适合的地方存储数组并覆盖其他随机内容)。

您也不需要强制转换 的返回值malloc,尽管它也没有坏处。

uint32_t physicalDeviceNumber = 0;
vkEnumeratePhysicalDevices(*instance, &physicalDeviceNumber, NULL);

VkPhysicalDevice **physicalDevice = malloc(physicalDeviceNumber * sizeof(VkPhysicalDevice*));
vkEnumeratePhysicalDevices(*instance, physicalDeviceNumber, physicalDevice);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在C语言中[foo] = bar是什么意思?

来自分类Dev

使用哪个:foo和foo:

来自分类Dev

如何在C语言中使用'æ','ø'和'å'进行操作

来自分类Dev

如何使用脚本/别名使bash / zsh将某些文本从“ foo.foo.foo”更改为“ foo foo foo”?

来自分类Linux

如何在C语言中使用原子变量?

来自分类Linux

如何在C语言中的Linux中使用共享内存

来自分类Dev

如何在C语言中使用strxfrm?

来自分类Dev

如何在C语言中使用指针

来自分类Dev

如何在C语言中使用VTK?

来自分类Dev

使用map <int,Foo>代替vector <Foo>避免指针失效

来自分类Java

Java语言中使用的哈希函数

来自分类Dev

使用 moduleFor('foo:bar', 'unit@foo:bar') 搜索并替换 moduleFor('foo:bar')

来自分类Dev

如何在PHP语言中使用OR

来自分类Dev

为什么以这种方式使用函数参数'foo':*(&foo)?

来自分类Dev

为什么使用Foo [T <:Bar]要求Foo [_ <:Bar]而不是Foo [_]

来自分类Dev

使用$ scope.foo和foo.vaue的好处

来自分类Dev

使用params [:foo]和@foo有什么区别?

来自分类Dev

如何使用sed将},{“ Foo”更改为} \ n {“ Foo”?

来自分类Dev

在Python中使用属性时Class.foo和instance.foo的不同行为

来自分类Dev

当foo被声明为可变的时,要求使用&mut foo而不是&foo的原因是什么?

来自分类Dev

foo((&i)++)在C语言中给出编译错误

来自分类Dev

不能在赋值中使用 &ingredients (type *[]foo.bar) 作为类型 []*foo.bar

来自分类Dev

使用C语言中的函数调用函数

来自分类Dev

这是避免在C语言中使用全局变量的策略,对吗?

来自分类Dev

foo(bar)和foo(bar,baz)

来自分类Dev

C语言中使用_Generic混合函数调用并返回常量的重载函数

来自分类Dev

<%= foo%>和$ {foo}之间的区别

来自分类Dev

在C语言中使用FILE变量的地址和FILE *有什么区别?

来自分类Dev

与在C语言中使用'\ n'和'\ 12'有什么区别

Related 相关文章

  1. 1

    在C语言中[foo] = bar是什么意思?

  2. 2

    使用哪个:foo和foo:

  3. 3

    如何在C语言中使用'æ','ø'和'å'进行操作

  4. 4

    如何使用脚本/别名使bash / zsh将某些文本从“ foo.foo.foo”更改为“ foo foo foo”?

  5. 5

    如何在C语言中使用原子变量?

  6. 6

    如何在C语言中的Linux中使用共享内存

  7. 7

    如何在C语言中使用strxfrm?

  8. 8

    如何在C语言中使用指针

  9. 9

    如何在C语言中使用VTK?

  10. 10

    使用map <int,Foo>代替vector <Foo>避免指针失效

  11. 11

    Java语言中使用的哈希函数

  12. 12

    使用 moduleFor('foo:bar', 'unit@foo:bar') 搜索并替换 moduleFor('foo:bar')

  13. 13

    如何在PHP语言中使用OR

  14. 14

    为什么以这种方式使用函数参数'foo':*(&foo)?

  15. 15

    为什么使用Foo [T <:Bar]要求Foo [_ <:Bar]而不是Foo [_]

  16. 16

    使用$ scope.foo和foo.vaue的好处

  17. 17

    使用params [:foo]和@foo有什么区别?

  18. 18

    如何使用sed将},{“ Foo”更改为} \ n {“ Foo”?

  19. 19

    在Python中使用属性时Class.foo和instance.foo的不同行为

  20. 20

    当foo被声明为可变的时,要求使用&mut foo而不是&foo的原因是什么?

  21. 21

    foo((&i)++)在C语言中给出编译错误

  22. 22

    不能在赋值中使用 &ingredients (type *[]foo.bar) 作为类型 []*foo.bar

  23. 23

    使用C语言中的函数调用函数

  24. 24

    这是避免在C语言中使用全局变量的策略,对吗?

  25. 25

    foo(bar)和foo(bar,baz)

  26. 26

    C语言中使用_Generic混合函数调用并返回常量的重载函数

  27. 27

    <%= foo%>和$ {foo}之间的区别

  28. 28

    在C语言中使用FILE变量的地址和FILE *有什么区别?

  29. 29

    与在C语言中使用'\ n'和'\ 12'有什么区别

热门标签

归档