Portál AbcLinuxu, 9. května 2025 21:41

Dotaz: strncpy přidává '\031' – bug v glibc?

stativ avatar 27.12.2009 11:29 stativ | skóre: 54 | blog: SlaNé roury
strncpy přidává '\031' – bug v glibc?
Přečteno: 429×
Odpovědět | Admin
Právě jsem narazil na prapodivný problém, kdy mi v jednom konkrétním případě strncpy přidává znak '\031' (end of medium?) na konec řetězce.

Dělá mi to na desktopu s Archem (32 bit) – jak s gcc 4.4.2 tak s clang 2.6, tudíž předpokládám, že pokud bug není u mě tak bude nejspíš v glibc (2.11.1). Když jsem to ale zkoušel na mašině s OpenSuSE (64bit) tak to jelo správně.

Ukázka kódu, který blbne:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char *test = "x^3 + (-x)^5";
    /*char *test = "sin(123 + 45 * ln(27 - 6))";*/
    char *str = malloc(strlen(test) * sizeof(char));

    strncpy(str, test, strlen(test));

    printf("%s\n",str);
}
Čekal bych, že na výstupu bude: x^3 + (-x)^5

ale já dostanu: x^3 + (-x)^5\031

Zvláštní je, že s jiným řetězcem (např. tím zakomentovaným to funguje).

Můj dotaz je – je bug u mě, nebo jinde?
Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

27.12.2009 11:40 0-58glfsdhesr
Rozbalit Rozbalit vše Re: strncpy přidává '\031' – bug v glibc?
Odpovědět | | Sbalit | Link | Blokovat | Admin
"Prekladac automaticky pridava ke kazde konstatne typu *char znak \0, aby funkce poznaly, kde konci" (volne podle K&R). Avsak strlen vraci delku bez \0 (man 3 strlen).

V tomto pripade by mozna stalo za to pouzit funkci strdup, ale nekdy se hodi si pamet alokovat rucne.

Doporucuju na ten kod spustit valgrind, ktery odhali chyby podobneho typu.
stativ avatar 27.12.2009 11:49 stativ | skóre: 54 | blog: SlaNé roury
Rozbalit Rozbalit vše Re: strncpy přidává '\031' – bug v glibc?
Jop, přesně tak. Ani mě nenapadlo, že bych mohl takovou chybu udělat (zvlášť, když jinde to mám správně).
Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk
stativ avatar 27.12.2009 11:46 stativ | skóre: 54 | blog: SlaNé roury
Rozbalit Rozbalit vše Re: strncpy přidává '\031' – bug v glibc?
Odpovědět | | Sbalit | Link | Blokovat | Admin
Safra, já zapomněl na plus jedna.
Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk
27.12.2009 16:48 KS | skóre: 10 | blog: blg | Horní polní u západní dolní
Rozbalit Rozbalit vše Re: strncpy přidává '\031' – bug v glibc?
Měl byste se raději podívat na význam základních operátorů v C++, protože sizeof(test) vrátí délku celého pole, namísto volání strlen(test), násobení sizeof(char) a přičítání jedničky. Nejen, že použití sizeof(test) je elegantnější, ale narozdíl od Vámi prezentovaného řešení má konstatní složitost (strlen(test) má lineární složitost!).
Pochybnost, nejistota - základ poznání
AraxoN avatar 27.12.2009 17:59 AraxoN | skóre: 47 | blog: slon_v_porcelane | Košice
Rozbalit Rozbalit vše Re: strncpy přidává '\031' – bug v glibc?
Neviem ako v C++, ale v C sizeof(test) vráti veľkosť dátového typu "smerník".
27.12.2009 18:25 Vojtěch Horký | skóre: 39 | blog: Vojtův zápisník | Praha
Rozbalit Rozbalit vše Re: strncpy přidává '\031' – bug v glibc?
protože sizeof(test) vrátí délku celého pole
Jenže zde jde o pointer! Velikost celého pole může sizeof vrátit pouze pokud jde o pole v době deklarace. Prostě:
int a[10];
int *pa = a;
// sizeof(a) = 10*sizeof(int) != sizeof(pa) = sizeof(void *)
I am always ready to learn although I do not always like to be taught. (W. Churchill)
stativ avatar 27.12.2009 19:15 stativ | skóre: 54 | blog: SlaNé roury
Rozbalit Rozbalit vše Re: strncpy přidává '\031' – bug v glibc?
To je pěkný, ale je to pointer. Navíc sizeof vrací alokovanou paměť, ne tu, která je řetězcem reálně obsazená.
Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.