Поток 1: неустранимая ошибка: диапазон перекрытия UnsafeMutablePointer.initialize - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь использовать

UnsafeMutablePointer<UnsafeMutablePointer<Float>?>!

как требуется для параметра для метода, который мне нужно использовать. Тем не менее я понятия не имею, что это такое или как его использовать.

Я создал это значение следующим образом:

 var bytes2: [Float] = [39, 77, 111, 111, 102, 33, 39, 0]
    let uint8Pointer2 = UnsafeMutablePointer<Float>.allocate(capacity: 8)
    uint8Pointer2.initialize(from: &bytes2, count: 8)

    var bytes: [Float] = [391, 771, 1111, 1111, 1012, 331, 319, 10]
    var uint8Pointer = UnsafeMutablePointer<Float>?.init(uint8Pointer2)
    uint8Pointer?.initialize(from: &bytes, count: 8)

    let uint8Pointer1 = UnsafeMutablePointer<UnsafeMutablePointer<Float>?>!.init(&uint8Pointer)
    uint8Pointer1?.initialize(from: &uint8Pointer, count: 8)

Но я получаю ошибку:

Thread 1: Fatal error: UnsafeMutablePointer.initialize overlapping range

Что я делаю не так?

1 Ответ

0 голосов
/ 05 сентября 2018

Вы создаете плохое поведение ..

var bytes2: [Float] = [39, 77, 111, 111, 102, 33, 39, 0]
let uint8Pointer2 = UnsafeMutablePointer<Float>.allocate(capacity: 8)
uint8Pointer2.initialize(from: &bytes2, count: 8)

Создает указатель на некоторую память и инициализирует эту память значениями, хранящимися в bytes2 ..

Итак: uint8Pointer2 = [39, 77, 111, 111, 102, 33, 39, 0]


Затем вы решили создать указатель, который ссылается на память этого указателя:

var uint8Pointer = UnsafeMutablePointer<Float>?.init(uint8Pointer2)

Так что, если вы напечатаете uint8Pointer, он будет иметь ТОЧНЫЕ значения, аналогичные uint8Pointer2 .. Если вы также решите изменить любое из его значений, он также изменит значения uint8Pointer2 ..

Итак, когда вы делаете:

var bytes: [Float] = [391, 771, 1111, 1111, 1012, 331, 319, 10]
uint8Pointer?.initialize(from: &bytes, count: 8)

Переписаны значения uint8Pointer2 с [391, 771, 1111, 1111, 1012, 331, 319, 10] ..


Пока что uint8Pointer - это просто мелкая копия uint8Pointer2 .. Изменение одного влияет на другое ..

Теперь вы решили сделать:

let uint8Pointer1 = UnsafeMutablePointer<UnsafeMutablePointer<Float>?>!.init(&uint8Pointer)
uint8Pointer1?.initialize(from: &uint8Pointer, count: 8)

Здесь вы создали указатель (uint8Pointer1) на uint8Pointer и сказали: uint8Pointer1 initialize с uint8Pointer .. но вы инициализируете указатель с указателем на себя и счетчиком 8 ..

Прежде всего, не беспокойтесь о вызове initialize для указателя на указатель со значением самого себя ... Он уже указывает на правильные значения ..

Что приятно, так это:

uint8Pointer1?.initialize(from: &uint8Pointer, count: 1)
//Same as:  memcpy(uint8Pointer1, &uint8Pointer, sizeof(uint8Pointer)`
//However, they both point to the same memory address..

вылетит, но:

uint8Pointer1?.initialize(from: &uint8Pointer)
//Same as: `uint8Pointer1 = uint8Pointer`.. Note: Just a re-assignment.

не будет .. потому что он не делает memcpy для последнего .. тогда как первый делает.

Надеюсь, я все правильно объяснил ..

P.S. Назовите ваши переменные правильно!


Перевод для людей C ++:

//Initial pointer to array..
float bytes2[] = {39, 77, 111, 111, 102, 33, 39, 0};
float* uint8Pointer2 = &bytes[2];
memcpy(uint8Pointer2, &bytes2[0], bytes2.size() * sizeof(float));

//Shallow/Shadowing Pointer...
float* uint8Pointer = uint8Pointer2;
float bytes[] = {391, 771, 1111, 1111, 1012, 331, 319, 10};
memcpy(uint8Pointer, &bytes[0], bytes.size() * sizeof(float));

//Pointer to pointer..
float** uint8Pointer1 = &uint8Pointer;

//Bad.. uint8Pointer1 and &uint8Pointer is the same damn thing (same memory address)..
//See the line above (float** uint8Pointer1 = &uint8Pointer)..
memcpy(uint8Pointer1, &uint8Pointer, 8 * sizeof(uint8Pointer));
//The memcpy is unnecessary because it already pointers to the same location.. plus it's also wrong lol.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...