Как правильно проверить значения перед выполнением memmove()?

#c

Вопрос:

Я использую memmove и иногда получаю адрес EXC_BAD_ACCESS KERN_INVALID_ADDRESS. Я хочу предварительно проверить исходящие значения, чтобы предотвратить эту ошибку.

Это из проекта c открытым исходным кодом, который больше не поддерживается. Я могу создать и запустить его, и он отлично работает, но я не знаю, как изменить код на C, чтобы сделать следующий код более безопасным для запуска:

 int
fe_shift_frame(fe_t * fe, int16 const *in, int32 len)
{
    int offset, i;

    if (len > fe->frame_shift)
        len = fe->frame_shift;
    offset = fe->frame_size - fe->frame_shift;

    /* Shift data into the raw speech buffer. */
    memmove(fe->spch, fe->spch   fe->frame_shift,
            offset * sizeof(*fe->spch));

    return 0;
}
 

источник: github

Я хочу предотвратить ошибки memmove, то есть; не выполняйте memmove, когда он не может быть перемещен, и он даст EXC_BAD_ACCESS KERN_INVALID_ADDRESS. Что-то вроде этого: (с AreTheValuesNotOK?????)

 int
fe_shift_frame(fe_t * fe, int16 const *in, int32 len)
{
    int offset, i;

    if (len > fe->frame_shift)
        len = fe->frame_shift;
    offset = fe->frame_size - fe->frame_shift;

    if (AreTheValuesNotOK?????)
        return -1;

    /* Shift data into the raw speech buffer. */
    memmove(fe->spch, fe->spch   fe->frame_shift,
            offset * sizeof(*fe->spch));

    return 0;
}
 

Из-за моего незнания языка Си (потому что я обычно развиваюсь с помощью C#) я не могу этого понять.
Что я могу понять, так это то, что » fe «все еще жив, когда используется memmove (), потому что он не падает до memmove (), в то время как» fe » уже использовался до этого, и также не выполняются асинхронные операции.
источник fe: github

Итак, как я могу написать код на c, чтобы проверить все значения, входящие в memmove, перед его вызовом?

Комментарии:

1. Я думаю, что вам нужно больше расследовать, чтобы сделать правильное решение. вы говорите, что fe все еще живы, т. е. не освобождены, и я думаю, что это нормально. посмотрите на аргументы memmove() вопроса: » fe->spch указатель в порядке?» как насчет offset и fe->spch fe->frame_shift ? также EXC_BAD_ACCESS , похоже, это «яблочная штука», я нашел эту статью, которая может помочь вам в расследовании сбоев доступа к памяти

2. @MarcoLucidi спасибо за ответ. Это действительно вещь для Apple iOS. В настоящее время я ищу не исправление, а просто профилактику, в некотором роде просто проверяя все значения. Я просто не знаю грамматики о том, как, например, проверить, является ли fe->spch нулевым или пустым или достаточно большим. memmove(XX 20, XX 15, ….) Также не имеет особого смысла для меня в документации memmove, которую я нашел. Поэтому я понятия не имею, как выполнить простую проверку 🙁

3. проверить, например, NULL легко if (fe->spch != NULL) { /* do your stuff */ } . проверка уже освобожденной памяти или емкости буфера — это совсем другая история. в c у нас нет » len() «, обычно вы не можете получить размер буфера только по его указателю. вы должны найти точку, где была выделена память и с каким размером. если вам повезет, размер может храниться внутри fe структуры рядом с указателем, или, может быть, это #define константа d, или где-то еще. существуют инструменты, которые помогают вам отслеживать ошибки в памяти, например valgrind , AddressSanitizer . также поможет отладчик ( gdb ).

4. @MarcoLucidi спасибо за всю вашу помощь. Я нашел «fe->frame_size», который должен указывать некоторый размер, потому что memmory был выделен с этим значением. Я не буду утруждать себя проверкой НУЛЯ, потому что он никогда не равен НУЛЮ, всегда какое-то значение указателя. Я просто проверю, больше ли смещение длина символа, чем размер кадра, это единственное, что я могу сделать.