#c #gcc #c99 #gcc9
Вопрос:
У меня есть функция, которая выглядит так:
int lexWhitespace(TokenizerOutput* input) {
printf("he");
if (!(14 > input->toStillParse[0] > 8) amp;amp; !(input->toStillParse[0] == 32)) {
// checks if the first character in the toStillParse section of input is whitespace.
return -1;
} else {input->tokenizerOutput[0] = input->toStillParse[0];}
for (int i = 1; ; i ) {
if ((14 > input->toStillParse[0] > 8) || (input->toStillParse[0] == 32)) {
// checks if the first character in the toStillParse section of input is whitespace.
input->tokenizerOutput[i] = input->toStillParse[i];
} else {return 0;}
}
}
это включает в себя эту структуру:
struct TokenizerOutput {
const char* toStillParse; // holds the text that still needs to be parsed.
char* tokenizerOutput; // holds the text that was just output by tokenizer function.
};
typedef struct TokenizerOutput TokenizerOutput;
Когда я пытаюсь вызвать его в основной функции, как это:
int main(void) {
printf("hellon");
TokenizerOutput j = {" k", " "};
printf("%sn", (amp;j)->toStillParse);
lexWhitespace(amp;j);
return 0;
}
Я получаю сегфолт. Segfault происходит до того, как функция lexWhitespace вообще что-либо запускает, потому что она не печатает «он». Я понятия не имею, почему это происходит. Любая помощь была бы очень признательна. Я использую gcc 9.3.0.
Комментарии:
1. Строковые литералы, как правило, недоступны для записи. Вы получите ту же ошибку с
char *x = " "; x[0] = 'a';
2. изменить
printf("he");
наprintf("hen"); fflush(stdout);
Ответ №1:
В этом коде есть некоторые ошибки.
Во-первых, это условие:
14 > input->toStillParse[0] > 8
Это, вероятно, непреднамеренно. Вероятно, это должно быть написано как:
14 > input->toStillParse[0] amp;amp; input->toStillParse[0] > 8
Во-вторых, этот цикл может никогда не завершиться:
for (int i = 1; ; i ) {
if ((14 > input->toStillParse[0] > 8) || (input->toStillParse[0] == 32)) {
// checks if the first character in the toStillParse section of input is whitespace.
input->tokenizerOutput[i] = input->toStillParse[i];
} else {return 0;}
}
Обратите внимание, что сравниваемый символ, toStillParse[0]
, является одним и тем же символом на каждой итерации цикла. Таким образом, этот цикл либо завершится немедленно, либо будет продолжаться вечно (и, вероятно, произойдет сбой / segfault). Похоже [0]
, так и должно быть [i]
. Также обратите внимание, что условие, вероятно, написано неправильно.
В C, x > y > z
это не то же самое, что x > y amp;amp; y > z
. Всякий раз , когда вы видите x > y > z
, это, вероятно, неправильно (если только вы не просматриваете записи IOCCC или что-то в этом роде).
Комментарии:
1. Это забавно. Я еще не совсем дошел до этой части. Спасибо!