Почему использование `cblas_ccopy` вызывает периодические ошибки памяти? - PullRequest
0 голосов
/ 21 мая 2018

Код ниже просто пытается скопировать значения из одного указателя в другой, используя 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 ]

0 голосов
/ 21 мая 2018

Используйте cblas_scopy вместо cblas_ccopy.cblas_ccopy копий (с одинарной точностью) сложных чисел, которые в два раза больше, чем числа с одинарной точностью, которые вы фактически используете, поэтому вы переполняете конец буфера.

0 голосов
/ 21 мая 2018

Префикс 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.)

...