Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Segmentation fault při předání variabilního počtu parametrů jiné variadické funkci (snprintf)

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Ghost07
Člen
Avatar
Ghost07:22.11.2022 11:46

Ahoj, abych nemusel po každém zápisu do bufferu kontrolovat, jestli se podařilo vše zapsat, tak jsem vytvořil pomocnou funkci, která se o to bude starat. Ale zdá se, že neumím správně předat variabilní počet argumentů do snprintf prostřednictvím jiné variadické funkce. Zkoušel jsem to podle téhle ukázky: https://stackoverflow.com/a/1056442

Zkusil jsem:

#include <stdio.h>
#include <stdarg.h>

#define HTML_BUF_LEN 4 * 1024

static char html_buf[HTML_BUF_LEN];

/**
 * write_to_buffer()
 */
static void write_to_buffer(const char *format, ...)
{
    static unsigned int len = 0;
    unsigned int written;

    va_list args;
    va_start(args, format);
    written = snprintf(html_buf + len, HTML_BUF_LEN - len, format, args);
    va_end(args);
    if (len + written >= HTML_BUF_LEN)
    {
        html_buf[len] = '\0';
        printf("%s(): Write failed. Buffer is full.", __func__);
        // TODO: flush buffer to http stream and repeat write
        return;
    }
    len += written;
}

/**
 * test1()
 */
void test1()
{
    char type[10];
    char name[10];
    char value[10];

    snprintf(type, 10, "%s", "number");
    snprintf(name, 10, "%s", "hodnota1");
    snprintf(value, 10, "%f", 0.5f);

    printf("<input type=\"%s\" name=\"%s\" value=\"%s\">\n", type, name, value);

    write_to_buffer("<input type=\"%s\" name=\"%s\" value=\"%s\">\n", type, name, value);
}

/**
 * main()
 */
int main(void)
{
    test1();

    printf("%s", html_buf);
}

Výstup po spuštění:

<input type="number" name="hodnota1" value="0.500000">
Segmentation fault (core dumped)

Výstup z gdb test1

Reading symbols from test1...
(gdb) run
Starting program: *hidden*/test1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
<input type="number" name="hodnota1" value="0.500000">

Program received signal SIGSEGV, Segmentation fault.
__strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex.S:450
450     ../sysdeps/x86_64/multiarch/strlen-evex.S: No such file or directory.
(gdb)
 
Odpovědět
22.11.2022 11:46
Avatar
Ghost07
Člen
Avatar
Ghost07:22.11.2022 12:00

Aha, zase mi to došlo pár minu po tom co jsem to sepsal a odeslal :D

Nenapadlo mě kouknout jaký je rozdíl mezi snprintf() a vfprintf(), a vůbec mi nepřišlo podezřelý, že v té ukázce použil právě to vfprintf(), myslel jsem, že to je kvůli výpisu do stderr. Takže jestli chci předat va_args, tak se na to má použít vsprintf(), s tím už to funguje.

 
Nahoru Odpovědět
22.11.2022 12:00
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.