AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79057200
Accepted
Tenobaal
Tenobaal
Asked: 2024-10-05 21:51:34 +0800 CST2024-10-05 21:51:34 +0800 CST 2024-10-05 21:51:34 +0800 CST

Saída para stdout ou stderr quando falta memória

  • 772

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.

c
  • 3 3 respostas
  • 102 Views

3 respostas

  • Voted
  1. Best Answer
    dbush
    2024-10-05T22:05:08+08:002024-10-05T22:05:08+08:00

    Em sistemas POSIX, a writefunção invoca diretamente a writechamada do sistema, portanto, nenhuma alocação de memória ocorre ali.

    O Windows tem uma _writefunção que faz parte de sua camada de compatibilidade POSIX e também está documentada para invocar o sistema operacional diretamente sem buffer :

    Essas funções invocam o sistema operacional diretamente para operações de nível mais baixo do que aquelas fornecidas pela E/S de fluxo. Chamadas de entrada e saída de baixo nível não armazenam em buffer nem formatam dados.

    Então você pode fazer isso:

    #ifdef _MSC_VER
    #include <io.h>
    #define write_str_no_alloc(str) _write(2, str, sizeof(str))
    #else
    #define write_str_no_alloc(str) write(STDERR_FILENO, str, sizeof(str))
    #endif
    

    Observe que isso requer que o argumento seja uma string literal ou uma matriz, caso contrário sizeofnão dará o resultado desejado.

    • 3
  2. Gabriel Staples
    2024-10-05T22:37:41+08:002024-10-05T22:37:41+08:00

    Você pode escrever sua própria safe_printf()função que nunca chama malloc(). Das minhas perguntas e respostas aqui: Quais chamadas de print em C NÃO chamam malloc()por baixo dos panos? :

    Aqui está uma safe_printf()função que nunca chama malloc()!

    Acabei escrevendo uma safe_printf()função que nunca chama malloc(), caso alguém precise dela. Eu testei e funciona bem dentro de malloc(). Ela usa a write()chamada de sistema (disponível no Linux, mas não em C padrão) para escrever os caracteres em stdout.

    Aqui está:

    ...

    #define SAFE_PRINTF_BUF_SIZE 2048
    __attribute__((__format__(printf, 1, 2)))
    int safe_printf(const char *format, ...)
    {
    

    ...

    Basta substituir write()na minha safe_print()função pela de @dbushwrite_str_no_alloc() para que funcione tanto no Windows quanto no Linux. Ou use WriteFile()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 ):

    safe_printf("Failed to get a timestamp. errno = %i: %s\n",
        errno, strerror(errno));
    
    • 0
  3. chux - Reinstate Monica
    2024-10-06T02:45:12+08:002024-10-06T02:45:12+08:00

    Se a escolha final for printf()(saída para stdout), certifique-se de usar a fflush(stdout)para garantir que ela seja exibida.

    Especialmente em caso de erro e com as muitas regras sobre descarga, é melhor divulgar esta mensagem.

    • -1

relate perguntas

  • Multiplicação mais rápida que *

  • Usando uma macro para comprimento de string no especificador de formato scanf () em C

  • Como você pode definir o tipo de dados de #define para long double?

  • Ponteiros const incompatíveis

  • Mudança de cor não gradual no OpenGL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve