Как насчет того, чтобы установить его с JavaScript?
var e = document.getElementById('cardNumber');
e.autocomplete = 'off'; // Maybe should be false
Это не прекрасно, но Ваш HTML будет допустим.
It is possible that the structure is located in memory that has been free()
'd, or the heap is corrupted. In that case, malloc()
could be modifying the memory, thinking that it is free.
You might try running your program under a memory checker. One memory checker that supports Mac OS X is valgrind, although it supports Mac OS X only on Intel, not on PowerPC.
* результат = malloc (realLength); // ???
Адрес вновь выделенного сегмента памяти сохраняется в месте, на которое ссылается адрес, содержащийся в переменной «результат».
Это намерение? Если это так, возможно, потребуется изменить strlcpy.
char * p = NULL;
p[i] is like
p += i;
which is a valid operation, even on a nullpointer. it then points at memory location 0x0000[...]i
Вы всегда должны проверять, является ли информация-> kind.name-> data нулевым значением, но в этом случае
в
if (*result == NULL)
freeParsedData(information);
return -1;
}
вы пропустили {
, это должно быть
if (*result == NULL)
{
freeParsedData(information);
return -1;
}
Это веская причина для использования этого стиля кодирования вместо
if (*result == NULL) {
freeParsedData(information);
return -1;
}
, где вы можете не заметить недостающую скобку, потому что вы привыкли к форме блока кода без скобки, отделяющей его от предложения if.
Вау, это странно. Одна вещь кажется мне немного подозрительной, хотя она может и не способствовать:
Что произошло бы, если бы информация и данные были хорошими указателями (не нулевыми), а значение information.kind.name было нулевым. Вы не разыменовываете этот указатель до строки strlcpy, поэтому, если он был нулевым, он мог не аварийно завершить работу до этого момента. Конечно, раньше, чем вы выполняете разыменование данных [1], чтобы установить их в \ 0, что также должно привести к сбою, но из-за какой-либо случайности ваша программа может просто иметь доступ на запись к 0x01, но не к 0x00.
Кроме того, я вижу, что вы используете информацию-> name.length в одном месте, а информацию-> kind.name.length в другом, не уверен, что это опечатка или желательно.
Отсутствие символа '{' после последнего оператора if означает, что что-то в разделе «// ... код выше пропущен, не имеет отношения ...» контролирует доступ ко всему этому фрагменту кода. Из всего вставленного кода выполняется только strlcpy. Решение: никогда не используйте операторы if без фигурных скобок для пояснения элемента управления.
Учтите это ...
if(false)
{
if(something == stuff)
{
doStuff();
.. snip ..
if(monkey == blah)
some->garbage= nothing;
return -1;
}
}
crash();
Только "crash ();" будет казнен.
Несмотря на то, что разыменование нулевого указателя приводит к неопределенному поведению и не обязательно к сбою, вы должны проверить значение информация-> вид.имя-> данные
а не содержимое информация-> вид.имя-> данные [1]
.
Я бы запустил вашу программу под valgrind . Вы уже знаете, что существует проблема с указателями NULL, поэтому профилируйте этот код.
Преимущество того, что здесь существует valgrind, состоит в том, что он проверяет каждую ссылку на указатель и проверяет, была ли эта ячейка памяти ранее объявлена, и сообщит вам номер строки, структура и все, что вам нужно знать о памяти.
Как уже упоминалось, ссылка на ячейку памяти 0 - это своего рода «que sera, sera».
Мое паучье чутье с оттенком C - это говоря мне, что вы должны разбить эти структурные переходы на линии
if (information->kind.name->data[information->kind.name->length] != '\0') {
, например,
if (information == NULL) {
return -1;
}
if (information->kind == NULL) {
return -1;
}
и так далее.
Меня интересует приведение символов * в вызове strlcpy.
Могут ли данные типа * отличаться по размеру от символа * в вашей системе? Если указатели символов меньше, вы можете получить подмножество указателя данных, которое может иметь значение NULL.
Пример:
int a = 0xffff0000;
short b = (short) a; //b could be 0 if lower bits are used
Изменить : орфографические ошибки исправлены.
Моя теория состоит в том, что информация-> вид.имя-> длина
является очень большим значением, так что информация-> вид.имя-> данные [информация -> kind.name-> length]
на самом деле относится к действительному адресу памяти.
Действие разыменования NULL-указателя не определено стандартом. Не гарантируется сбой, и часто этого не произойдет, если вы действительно не попытаетесь записать в память.
As an FYI, when I see this line:
if (information->kind.name->data[information->kind.name->length] != '\0') {
I see up to three different pointer dereferences:
You check information for non-null, but not name and not data. What makes you so sure that they're correct?
I also echo other sentiments here about something else possibly damaging your heap earlier. If you're running on windows, consider using gflags to do things like page allocation, which can be used to detect if you or someone else is writing past the end of a buffer and stepping on your heap.
Saw that you're on a Mac - ignore the gflags comment - it might help someone else who reads this. If you're running on something earlier than OS X, there are a number of handy Macsbugs tools to stress the heap (like the heap scramble command, 'hs').
Возможно, вы столкнулись с повреждением стека. Строка кода, на которую вы ссылаетесь, может вообще не выполняться.
Эффект разыменования нулевого указателя не определен стандартом, насколько мне известно.
Согласно стандарту C 6.5.3.2/4:
Если указателю присвоено недопустимое значение, поведение унарного оператора * не определено.
Так что сбой может быть, а может и не быть.
Here's one specific way you can get past the 'data' pointer being NULL in
if (information->kind.name->data[information->kind.name->length] != '\0') {
Say information->kind.name->length is large. Atleast larger than 4096, on a particular platform with a particular compiler (Say, most *nixes with a stock gcc compiler) the code will result in a memory read of "address of kind.name->data + information->kind.name->length].
At a lower level, that read is "read memory at address (0 + 8653)" (or whatever the length was). It's common on *nixes to mark the first page in the address space as "not accessible", meaning dereferencing a NULL pointer that reads memory address 0 to 4096 will result in a hardware trap being propagated to the application and crash it.
Reading past that first page, you might happen to poke into valid mapped memory, e.g. a shared library or something else that happened to be mapped there - and the memory access will not fail. And that's ok. Dereferencing a NULL pointer is undefined behavior, nothing requires it to fail.
Во-первых, разыменование нулевого указателя является неопределенным поведением. Это может привести к сбою, но не к сбою или установке обоев на изображение Губки Боба Квадратные Штаны.
Тем не менее, разыменование нулевого указателя обычно приводит к сбою. Таким образом, ваша проблема, вероятно, связана с повреждением памяти, например, из-за записи после конца одной из ваших строк. Это может вызвать сбой с отсроченным эффектом. Я особенно подозреваю, потому что маловероятно, что malloc (1)
выйдет из строя, если только ваша программа не столкнется с концом доступной виртуальной памяти, и вы, вероятно, заметили бы, если бы это было так.
Edit: OP указал, что нулевым результатом является не результат, а информация-> вид.имя-> данные
. Вот потенциальная проблема:
Нет проверки для информации-> kind.name-> data
имеет значение null. Единственная проверка на это -
if (information->kind.name->data[information->kind.name->length] != '\0') {
. Предположим, что information-> kind.name-> data
имеет значение null, но information-> kind.name-> length, скажем, равно 100. Тогда это утверждение будет эквивалент:
if (*(information->kind.name->data + 100) != '\0') {
Что не разыменовывает NULL, а разыменовывает адрес 100. Если это не приводит к сбою и адрес 100 содержит 0, то этот тест будет пройден.