Как небезопасно увеличить размер изменяемого фрагмента байтов? - PullRequest
0 голосов
/ 09 мая 2019

У меня есть эта функция:

use std::io;

pub fn recv(mut buf: &mut [u8]) -> io::Result<usize> {
    let size_to_extend = 50; // I want to increase the size of "buf" by 50
    unsafe {
        /* ??? */
    }
}

Как настроить размер массива buf, даже если это параметр? Необходимо, чтобы этот метод должен был произойти.

1 Ответ

2 голосов
/ 09 мая 2019

То, что вы пытаетесь сделать, это все-но- гарантированно вызывать неопределенное поведение. Найти лучший API .


Если вы хотите, чтобы изменения были отражены вне функции, вам не повезло. Нет такой возможности, чтобы эта сигнатура функции позволила этому произойти, по той же причине, по которой fn foo(x: i32) не позволит вам изменить передаваемое значение в соответствии с наблюдением вызывающей стороны.

Если вам просто нужно это внутри функции, используйте slice::from_raw_parts. Я пометил всю функцию как unsafe, потому что некоторые входные данные будут вызывать неопределенное поведение, и этот код не может защититься от него:

use std::slice;

pub unsafe fn recv(buf: &mut [u8]) {
    let size_to_extend = 50;

    let ptr = buf.as_mut_ptr();
    let len = buf.len();
    let bad_idea = slice::from_raw_parts_mut(ptr, len + size_to_extend);

    for b in bad_idea.iter_mut() {
        *b = 10;
    }
}

Если вы можете изменить API, что-то вроде этого работает, чтобы показать изменение вне функции:

pub unsafe fn recv(buf: &mut &mut [u8]) {
    let size_to_extend = 50;

    let ptr = buf.as_mut_ptr();
    let len = buf.len();
    let bad_idea = slice::from_raw_parts_mut(ptr, len + size_to_extend);

    for b in bad_idea.iter_mut() {
        *b = 10;
    }

    *buf = bad_idea;
}

Смотри также:

...