\n Ломает вывод строки Си

Имею вот такую функцию:

char *custom_strerror(int errcode) {
  char *error = NULL;
  if (errcode >= 0 && errcode <= 106) {
    error = ErrorNames[errcode];
  } else {
    char num_error[20];
    sprintf(num_error, "%d", errcode); // поменять на свой
    char unknown[50] = "Unknown error: ";
    strcat(unknown, num_error);
    error = unknown;
  }
  return error;
}

В ErrorNames названия ошибок, к которым обращаюсь с помощью enum. Если ошибка попадает в диапазон существующих ошибок, то все в порядке, но вот когда не попадает, следующая проблема:

У меня вот такой вывод в мейне;

printf("%s\n", custom_strerror(-1))

Если добавлять перенос строки, выводится какая-то фигня: 'T??' или 'a??' или '???'. Без переноса строки вывод нормальный. Причем если ошибка попадает в диапазон, то и при использовании \n вывод остается нормальным. Что это такое?


Ответы (1 шт):

Автор решения: gbg

Все довольно просто - вы выделяете память под ваше сообщение об ошибке на стеке.

Когда вы обрабатываете известную ошибку, вы возвращаете указатель на элемент массива с ошибками (и здесь все работает нормально).

Когда вы обрабатываете неизвестную ошибку, вы ставите этот указатель куда-то на стек (char unknown[50]). Когда вы из функции выходите, все локальные переменные перестают существовать.

Обращение к несуществующей переменной на C - это неопределенное поведение. Программа может вести себя произвольным образом, в том числе и иногда (когда нет \n), работать нормально.

Проще всего переписать функцию так, чтобы она принимала буфер для формирования сообщения об ошибке, в качестве одного из параметров.

→ Ссылка