Portál AbcLinuxu, 13. května 2025 23:49

Dotaz: SegFault v dvorozmernem poli

5.5.2009 12:42 Marek Vojnar
SegFault v dvorozmernem poli
Přečteno: 195×
Odpovědět | Admin

Dobry den, mam nasledujici kod v C, prvni cast naalokuje pole retezcu s "boxes" radky a pro delku kazdeho retezce "BOXLEN+1" znaku. V tomto pripade je boxes rovno peti, kod tedy naalokuje misto pro pet retezcu.

V druhe casti kodu do kazdeho z peti retezcu nakopiruji nejaky text ("123"). Problem je vsak s poslednim retezcem (parts[4]), kdy mi program pri pokusu o jeho inicializaci pres strncpy hodi segmentation fault.

char **parts = (char **) malloc(boxes);
for (int i = 0; i < boxes; i++)
parts[i] = (char *) malloc(BOXLEN + 1);

strncpy(parts[0], "123", BOXLEN);
strncpy(parts[1], "123", BOXLEN);
strncpy(parts[2], "123", BOXLEN);
strncpy(parts[3], "123", BOXLEN);
strncpy(parts[4], "123", BOXLEN);

Nevite prosim, cim by to mohlo byt?

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

Odpovědi

5.5.2009 12:51 #Tom | skóre: 32 | blog: Inspirace, aneb co jsem kde vyhrabal
Rozbalit Rozbalit vše Re: SegFault v dvorozmernem poli
Odpovědět | | Sbalit | Link | Blokovat | Admin
Výše uvedený kód se mi nelíbí. Alokace pole ukazatelů se provádí takto:
parts = (char **) malloc(boxes * sizeof(char *));
Pokud je velikost ukazatele jiná než 1, což je prakticky všude, je přepisována nepřidělená paměť.

Moje další připomínky jsou více méně formální. Pokud je boxes < 4, pak je parts[3] poslední zapisovatelný prvek. Pokud je boxes makro nebo konstanta rovná nejméně pěti, o nic nejde.

Dalším problém může nastat, pokud BOXLEN < 4, protože se řetězce "123" s koncovým nulovým znakem nevejdou do alokovaných prostorů.
5.5.2009 12:54 #Tom | skóre: 32 | blog: Inspirace, aneb co jsem kde vyhrabal
Rozbalit Rozbalit vše Re: SegFault v dvorozmernem poli
Odpovědět | | Sbalit | Link | Blokovat | Admin
Tohle se mi nepovedlo.
Pokud je boxes < 4, pak je parts[3] poslední zapisovatelný prvek.
Pokud je boxes < 5, pak do parts[4] nepůjde zapisovat, tedy přidělit adresu pro alokovaný řetězec.
5.5.2009 13:06 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: SegFault v dvorozmernem poli
Odpovědět | | Sbalit | Link | Blokovat | Admin
char **parts = (char **) malloc(boxes * sizeof(char *));
A na to pozor.
5.5.2009 15:49 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: SegFault v dvorozmernem poli
Odpovědět | | Sbalit | Link | Blokovat | Admin
Problem vyresili uz ostatni, nicmene priste doporucuji spustit pod valgrindem a ten vypise vsechny chyby (pri praci s pameti) vcetne radku na kterych se nachazeji.
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
5.5.2009 17:47 kulik
Rozbalit Rozbalit vše Re: SegFault v dvorozmernem poli
Odpovědět | | Sbalit | Link | Blokovat | Admin

Dalsi mene napadna chyba je v

strncpy(parts[4], "123", BOXLEN);

kde by melo byt BOXLEN + 1, pokud tedy BOXLEN ma byt max. delka 
retezce (coz vyvozuju z alokace BOXLEN + 1 vyse). Jinak neni zajisten ukoncovaci null znak, protoze strncpy ho neresi. 

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.