【问题标题】:reserveCapacity(Swift) vs resize(C++)保留容量(Swift)与调整大小(C++)
【发布时间】:2021-07-12 16:57:00
【问题描述】:

我尝试将 C++ 代码转换为 Swift。我有这样一个用 C++ 编写的方法(简化示例)

std::vector<int> list;

void foo() {
...
  while(isOk) {
    list.resize(10000); //resize do it's job only if list.capasity < requested size

    for(int i = 0; i < 10000; i++) {
      list[i] = i;
    }
  }
...
}

Swift 方面:

var arr: [Int] = []

do {
  while true {
    arr.reserveCapacity(10000)
    
    for i in 0..<10000 {
      arr[i] = i
    }
  }
}

错误是:

错误:执行被中断,原因:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)。

根据文档reserveCapacity 分配请求的大小,但是为什么当我尝试向特定单元格写入内容时出现错误?

【问题讨论】:

  • 嘿 :) 你能解释一下,为什么你需要这个?特别是因为 Swift 中的数组在大小上是“动态的”。
  • @JasonRietzke 我不知道 swift,但在我看来,数组在 swift 中是动态的正是您想要一种保留容量的方式的原因。动态分配可能会变得昂贵,因此如果您预先知道要分配多少(即使是粗略的),保留内存比让 swift 处理它更有效。

标签: swift


【解决方案1】:

您将数组的底层存储与数组的实际大小混淆了。 Swift 中的数组是动态的,所以你可以append() 并且数组会相应地增长。 在内部,Swift 会为您管理底层内存的分配方式,因此您无需考虑。

当你reserveCapacity 时,这告诉 Swift 你预计数组最终会达到这个大小,所以它应该提前为你准备好内存。 它本质上只是您通常不需要进行的性能优化,除非您知道数组最终会增长到给定的大小。 这并不意味着数组现在已经用值初始化了这个内存,所以越界访问元素会导致崩溃。

如果你想要一个预先用值初始化的数组,你可以像这样使用init(repeating:count:) initializer

var arr = Array(repeating: 0, count: 10000)

这将为 10,000 个元素分配存储空间将每个值初始化为 0,因此现在您可以安全地访问此范围内的任何索引。

【讨论】:

    猜你喜欢
    • 2012-03-20
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多