Почему использование `cblas_ccopy` вызывает периодические ошибки памяти?
Код ниже просто пытается скопировать значения из одного указателя в другой, используя cblas_ccopy
, но это приводит к malloc: *** error ... incorrect checksum for freed object
ошибка около трети времени. Почему это не всегда работает?
import Accelerate
func testCopy() {
// set capacity
let capacity: Int = 1000
// destination array
let destinationArray = UnsafeMutablePointer<Float>.allocate(capacity: capacity)
destinationArray.initialize(repeating: 0, count: capacity)
// source array
let sourceArray = UnsafeMutablePointer<Float>.allocate(capacity: capacity)
sourceArray.initialize(repeating: 1, count: capacity)
// copy values
cblas_ccopy(Int32(capacity),
UnsafeRawPointer(sourceArray),
1,
UnsafeMutableRawPointer(destinationArray),
1)
// check to see if values were copied
for idx in 0..<capacity {
print(idx, destinationArray[idx])
}
}
testCopy()
При запуске в качестве модульного теста ошибка objc[44736]: autorelease pool page 0x7fecb903c000 corrupted
, Когда он запускается как скрипт, ошибка incorrect checksum
,
Я пытался установить точку останова в malloc_error_break
но я не понимаю, как интерпретировать вывод.
Я тоже пробовал проходить sourceArray
а также destinationArray
в cblas_ccopy
в качестве аргументов, без преобразования их в необработанные указатели, но это не помогло.
2 ответа
Использование cblas_scopy
вместо cblas_ccopy
, cblas_ccopy
копирует (с одинарной точностью) комплексные числа, которые в два раза больше, чем числа с одинарной точностью, которые вы фактически используете, так что вы переполняете конец буфера.
c
префикс в _ccopy
означает, что тип элемента является комплексом с одинарной точностью. Итак, в вашем cblas_ccopy(Int32(capacity),...)
оба указателя должны содержать capacity
элементы комплексных чисел одинарной точности, что 2 * capacity
элементы чисел с плавающей запятой одинарной точности.
Вы просто выделяете capacity
элементы чисел с плавающей запятой одинарной точности. Вы можете знать, что происходит, когда доступ к памяти превышает лимит памяти.
Попробуйте удвоить размер выделения:
let destinationArray = UnsafeMutablePointer<Float>.allocate(capacity: 2 * capacity)
destinationArray.initialize(repeating: 0, count: 2 * capacity)
// source array
let sourceArray = UnsafeMutablePointer<Float>.allocate(capacity: 2 * capacity)
sourceArray.initialize(repeating: 1, count: 2 * capacity)
// copy values
cblas_ccopy(Int32(capacity), //<- do not double here.
UnsafeRawPointer(sourceArray),
1,
UnsafeMutableRawPointer(destinationArray),
1)
(Или попробуйте выделить capacity
элементы комплексных чисел одинарной точности, не Float
.)