Como posso imprimir algo quando não tenho memória?
Tenho um conjunto personalizado de funções malloc[, realloc e calloc] e free. Por enquanto, o projeto apenas as usa como um wrapper para as versões normais das funções. Essas funções wrapper encerram o programa e devem dar uma saída para indicar o erro.
No momento, a função para emitir a mensagem de erro se parece com isto:
#ifdef __linux__
void memory_error() {
if (errno == ENOMEM)
printf("%s\n", "Out of memory or memory is limited. Fatal error. The program needs to terminate.");
else
printf("%s\n", "Memory allocation failed. Fatal error. The program needs to terminate.");
}
#else
void memory_error() {
printf("%s\n", "Memory allocation failed, likely due to being out of "
"memory or memory being limited for this program. "
"Fatal error. The program needs to terminate.");
}
#endif
O problema é que printf()
às vezes aloca memória e se eu estiver sem memória, isso falhará. Aloca fwrite()
memória? E se sim, há uma opção portátil (então sem chamada de sistema de gravação) para produzir algo sem ter que alocar mais memória?
Até agora, como solução funcional para sistemas Unix, eu poderia fazer isso:
#ifdef __unix__
#define write_str_no_alloc(str) write(STDERR_FILENO, str, sizeof(str))
#else
#define write_str_no_alloc(str) ???
#endif
Estou sentindo falta de uma solução para janelas. Eu preferiria uma solução geral para ambos, mas isso funcionaria para mim.
Em sistemas POSIX, a
write
função invoca diretamente awrite
chamada do sistema, portanto, nenhuma alocação de memória ocorre ali.O Windows tem uma
_write
função que faz parte de sua camada de compatibilidade POSIX e também está documentada para invocar o sistema operacional diretamente sem buffer :Então você pode fazer isso:
Observe que isso requer que o argumento seja uma string literal ou uma matriz, caso contrário
sizeof
não dará o resultado desejado.Você pode escrever sua própria
safe_printf()
função que nunca chamamalloc()
. Das minhas perguntas e respostas aqui: Quais chamadas de print em C NÃO chamammalloc()
por baixo dos panos? :Basta substituir
write()
na minhasafe_print()
função pela de @dbushwrite_str_no_alloc()
para que funcione tanto no Windows quanto no Linux. Ou useWriteFile()
a função do Windows como @Some programmer dude diz .Quero manter apenas um lugar para manter esse código, então coloque o código na minha resposta .
O uso é exatamente o mesmo que
printf()
.Exemplo (modificado da minha outra resposta aqui ):
Se a escolha final for
printf()
(saída parastdout
), certifique-se de usar afflush(stdout)
para garantir que ela seja exibida.Especialmente em caso de erro e com as muitas regras sobre descarga, é melhor divulgar esta mensagem.