#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 был выделен с этим значением. Я не буду утруждать себя проверкой НУЛЯ, потому что он никогда не равен НУЛЮ, всегда какое-то значение указателя. Я просто проверю, больше ли смещение длина символа, чем размер кадра, это единственное, что я могу сделать.