Sziasztok!
Csinálok egy elég egyszerű programot és ezt a hibaüzenetet kaptam:
*** glibc detected *** double free or corruption (out): 0x081370b8 ***
Ez mitől lehet?
Valahol a netetn azt találtam, hogy ha ezt használom, akkor megjavul:
export MALLOC_CHECK_=0
De nem működik. Mi lehet szerintetek a gond? Találkozott már valaki hasonlóval?
Üdv:
denx
- 2690 megtekintés
Hozzászólások
#include <stdlib.h>
int main()
{
void *a= malloc (8);
free(a);
free(a);
return 0;
}
- A hozzászóláshoz be kell jelentkezni
Köszi, erre gondoltam én is, de már minden free-t kiszedtem a progiból és még mindig ez van!
- A hozzászóláshoz be kell jelentkezni
gdb, strace, ltrace a barátod.
Milyen libeket használsz ?
Nem adsz meg valhol rosz pinter, ill. pointer - int keveredés?
Esetleg string vég '\0' hiányzik.
- A hozzászóláshoz be kell jelentkezni
én is ezeket javaslom, még nagyon hasznos tud lenni a valgrind
- A hozzászóláshoz be kell jelentkezni
ha ez megnyugtat a centos-t is kiadjak igy.
- A hozzászóláshoz be kell jelentkezni
Nem feltétlenül a te programodból hívódik meg közvetlenül a free(), lehet, hogy valamelyik másik C függvény amit használsz az hívja meg. Sajnos ezt máshogy nem lehet kideríteni így, csak debuggolással.
- A hozzászóláshoz be kell jelentkezni
továbbá: Electric Fence, illetve szorgos debuggolás: addig egyszerűsítjük a programot, amíg meg nem szűnik a hiba; az utoljára kivett rész okozta a gondot, vagy legalábbis köze volt hozzá.
Az ellenőrzés letiltása (MALLOC_CHECK) természetesen nem megoldás.
- A hozzászóláshoz be kell jelentkezni
#include <stdlib.h>
int main()
{
size_t *a=(size_t*) malloc (8);
a[-1]=(size_t)a;
a=(size_t*) realloc(a,0);
return 0;
}
Másik kód ami, előidézheti.
- A hozzászóláshoz be kell jelentkezni
arra meg nem gondoltal, h a[-1] eseten olyan memoriateruletre irsz ahova nagyon nem kene?
- A hozzászóláshoz be kell jelentkezni
Én kérek elnézést!
KisKresz
- A hozzászóláshoz be kell jelentkezni
Szerinted miért irtam :P
Talán azért, hogy példát mutassak olyan kódra ami ilyen hibát dob..
- A hozzászóláshoz be kell jelentkezni
jode ez lame kod barki aki egy oranal tobbet foglalkozott programozassal nem ir ilyet
- A hozzászóláshoz be kell jelentkezni
Kivéve, ha a[i]=blablabla formában teszi, ahol mondjuk i értéke hibás.
KisKresz
- A hozzászóláshoz be kell jelentkezni
Csak tömb indexbe kell hibás számnak kerülnie, a sok JÁVA fan pont azért is szereti jávát, mert ott szolnak érte.
-1 meg spec. érték.
- A hozzászóláshoz be kell jelentkezni
ha kicsit bonyolultabb a program/algoritmus, akkor mar annyira nem egyszeru a felszabaditas.. lama dolog ugyan, de tobbek kozt ezert terjednek annyira a garbage collector-os nyelvek (.net, java, scriptnyelvek)
az meg, hogy egy tombbol kiindexel, szinten szokasos, es sulyos hiba, es el szoktak kovetni.. eleg rakeresni a buffer overrun exploitokra.. ha raadasul stack-en van, akkor meg konnyen ki is lehet hasznalni betoresre..
---------------------
"A feny azt hiszi, gyorsabb mindennel, de teved. Mindegy, milyen sebesen szaguld a feny, mindig azt fogja talalni a vegen, hogy a sotetseg ert oda elsonek, es ra var." - Terry Pratchett
- A hozzászóláshoz be kell jelentkezni
Háhááá csak a garbage collector azellennemvéd. Ha valahol véletlenül megmarad a referencia az ovjektumra, akkor a gc nem tudja kihajítani és frankó memory leakeket lehet gyártani vele. (Lásd még: "Miért zabálják a memóriát a java-s programok?") Tény, hogy talán a problémák egy részét kiszűri a gc, de messze nem csodaszer. A java profiling viszont jó kis játék... jó sok időt el lehet vele tölteni és közben jó sok hajat tépni, mire megtalálja az ember, hogy valami bonyolultabb rekurzív algoritums lekódolásának hevében melyik változót felejtette el null-ra állítani. Plusz pontért más ember által írt kódban ugyanezt. :)
---
Keep on trolling
- A hozzászóláshoz be kell jelentkezni
Csak érdekesség képpen :-)
Én Knoppix leszármazott LiveCD-ről bootolva próbáltam partimage-gel backupot csinálni. kb 80%-nál a partimage pontosan ezzel a hibaüzenettel szállt el.
- A hozzászóláshoz be kell jelentkezni
mennyire bonyolult/hosszu a program?
---------------------
"A feny azt hiszi, gyorsabb mindennel, de teved. Mindegy, milyen sebesen szaguld a feny, mindig azt fogja talalni a vegen, hogy a sotetseg ert oda elsonek, es ra var." - Terry Pratchett
- A hozzászóláshoz be kell jelentkezni
Most kezd bonyolódni. Amúgy elég egyszerű a dolog és látszólag értelmetlen helyen akad ki. Sőt! Ha egy másik értelmetlen helyen feltöltöm a frissen allokált memóriát speciális értékekkel (-1) akkor kezd csak kiakadni!
Tanácstalan vagyok. Nem sok kedvemn van az egészet átnézni, de félek tőle, csak az marad!
- A hozzászóláshoz be kell jelentkezni
Biztos elegendő memóriát foglalsz? Nem felejtetted el megszorozni pl. egy sizeof(int) -el, 0 tol indexeled?.(Ne vedd sértésnek)
Nagyon valószínű, hogy valhol rosszul indexelsz pl. tömböt, és olyan helyre írsz ahhol malloc a memoria allokációs adatait tárolja.
Ha nem túl nagy a kód és nem túl bizalmas, akkor be is postolhatnád.
vagy pl. http://pastebin.com/ -en elhelyezhetnéd.
- A hozzászóláshoz be kell jelentkezni
Ez buffer over-, v. underflow. Valamelyik tomb cimzesed cseszed el.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Nemrég nekem is hasonlókat üzengetett (talán a 3.3-as fölötti gcc-vel, azt hiszem)
A g_free()-k helyett g_object_unref()-el szabadítottam fel a glib függvényei által foglalt területeket...
- A hozzászóláshoz be kell jelentkezni
Jah! Lehet nem írtam, de sima C nyelvű a probléma.
- A hozzászóláshoz be kell jelentkezni
foditsd debug modban, -g, valgrind (, gdb, strace).
ultra egy fos amit kikopnek, de erdemes atnezni es okulni belole. ha nem vilagos, akkor olvasni mig az nem lesz .... vagy atterni C# v. java-ra.
- A hozzászóláshoz be kell jelentkezni
Mindenkinek köszönöm a segítséget! Valgrind volt a megoldás!
Az eset nem volt annyira egyszerű, de megoldottam. Mindenki okulására itt a lényeg:
#define T_SIZE 20
typedef struct t2{
char c;
int i;
} t2_t;
typedef t2_t t1_t[T_SIZE];
/*...*/
t1_t *func(){
t1_t *res = calloc(sizeof(t1_t),1);
int j;
for(j=0;j<T_SIZE;j++){
res[j]->c='\1';
res[j]->i=-1;
}
return res;
}
Kijavítva:
/*...*/
t1_t *func(){
t1_t res;
int j;
for(j=0;j<T_SIZE;j++){
res[j].c='\1';
res[j].i=-1;
}
return &res;
}
Üdv:
denx
UI: Lehet a fenti kódban van hiba, de igyekeztem csak a lényeget kicserélni
- A hozzászóláshoz be kell jelentkezni
nem vok guru, de ez hibas... egy lokalos valtozot (res) adsz vissza fuggveny eredmenynek?
amugy szerintem
t1_t *res = calloc(sizeof(t2_t),T_SIZE);
--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
ansi c permits mixed code and declarations, vagy hogy is mondja. illendő betartani
t1_t *res=NULL
...
res=calloc(sizeof(t1_t),1);
...
return res;
SZVSZ így mennie kéne. első glancra. vagy az indexelés (de azt most este meg sem próbáltam felfogni. egész nap fizikáztam.)
- A hozzászóláshoz be kell jelentkezni
static t1_t res; //esetleg
szerk: nem ide kellett volna válaszolnom
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
ja, static megoldás lhet, de csak akkor ha csak 1-re van szükség ebból. vagy mindig memcpy-zni? na nemá'
- A hozzászóláshoz be kell jelentkezni
Nem hagytál edittálni:
t1_t *func(){
t2_t *res = calloc(sizeof(t1_t),1);
int j;
for(j=0;j<T_SIZE;j++){
res[j].c='\1';
res[j].i=-1;
}
return (t1_t*)res;
}
Ha nem rontottam el.
szerk: Elbandi callockja lehet, hogy szebb , de ide malloc is jó mivel úgy is a ciklusban kap értéket.
szerk2: Ha nem suliba készül,ezt az ősi szabvány-t nem fontos betartani, nem ismerek olyan fordítót ami nem támogatná.
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
Ha
[code]
[/code] közé teszed, emberibben néz ki...
--
trey @ gépház
- A hozzászóláshoz be kell jelentkezni
Kösz, relációs jelek is megmaradnak így, nagyon zsíír.
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
nekem valami nem tetszik ebben:
typedef t2_t t1_t[T_SIZE];
/*...*/
ennek nem
typedef t2_t[T_SIZE] t1_t;
nek kéne lennie?
ha a fentvel fordítod le (amit beírtál) nem csodálom ha hibás, és kiindexelsz.
- A hozzászóláshoz be kell jelentkezni
Nem.
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
??? ennyre este van?
nem így műxik?
typedef bla bla bla qqriq;
akkor:
qqriq foo;
ugyanaz mint
bla bla bla foo;
- A hozzászóláshoz be kell jelentkezni
Könyen öszezavar engem is :)
A fordító nem így eszi meg.
typedef struct/enum nál a végére kerül a név, a de a tömb (/függvény) fura állat.
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
való igaz. akkor ennyire este van.
egyébként logikus.
int a[4];
a helyes és nem
int[4] a;
mind1. zsibbad az agyam, és utálom a csatolt rezgéseket.
- A hozzászóláshoz be kell jelentkezni
Gyerekek ti mind nagyon fáradtak vagytok. :)
denx, te kijavítottál egy hibát, és beraktál egy másikat. :)
A calloc kell (vagy inkább malloc) mert különben a lokális változót turkálod, ami visszatéréskor "eltűnik". Persze ez akkor tűnik fel, mikor egy következő fv hívás felülírja a vermet.
Viszont ügyesen észrevetted, hogy "res[j]->c" helyett "res[j].c" kell.
(Perverzeknek "(res+j)->c").
(Egyébként a struct mögé nem kell a t2.)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
még perverzebeknek (és még fáradtabbaknak):
(*(res+j)).c
de lehet a külső () fölösleges. :)
- A hozzászóláshoz be kell jelentkezni
Ezt majdnem odaírtam én is, de aztán mégse, elvégre a "->"-at kb így szokták bevezetni a könyvekben. :)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
mostmár jól szét lett offolva téma, de vajon megoldás született-e már?
- A hozzászóláshoz be kell jelentkezni
Persze. Ő írta be, igaz 2 részletben. :)
Látom fáradtak vagytok, pedig csak most kezdődik az éjszaka.
/*...*/
t1_t* func(){
t1_t *res;
int j;
res=(t1_t*) calloc(sizeof(t1_t),1);
for(j=0;j<T_SIZE;j++){
res[j].c='\1';
res[j].i=-1;
}
return res;
}
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
In function 'func':
error: request for member 'c' in something not a structure or union
error: request for member 'i' in something not a structure or union
Nem figyelsz, faradt vagy!
Mondom tipus!
t1_t* func(){
t1_t *res;
int j;
res=(t1_t*) calloc(sizeof(t1_t),1);
for(j=0;j<T_SIZE;j++){
(*res)[j].c='\1';
(*res)[j].i=-1;
}
return res;
}
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
Oh my God!
Mentségemre legyen mondva 4-5 éve nem írtam C-ben semmit.
Ilyen kódot meg soha... Ezek a typedefek brrrr.
Akkor legyen inkább:
t2_t* func(){
t2_t *res;
int j;
res=(t2_t*) calloc(sizeof(t2_t),T_SIZE);
for(j=0;j<T_SIZE;j++){
res[j].c='\1';
res[j].i=-1;
}
return res;
}
Ez így talán a legkevésbé undorító leginkább C-s.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Akkor is enyim lesz az utolso szo ! :D
Igy gyorsabb, kb egy memset -el.
res=(t2_t*) malloc(sizeof(t2_t)*T_SIZE);
typedefelet (constans meretu) struktura tomb valoban eleg attekintehetetlen tud lenni.
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
Szorakozzatok!,
HF:
mi let volna ha nem valtok tipust? :))
Legalabb 3 fele varacio eri a max pontot :-D
Felesleges tobbet kitalalni. :P
szerk:
Na meg harmat :)
------
gentóhuszár
- A hozzászóláshoz be kell jelentkezni
a callocos castingra gondolsz? semmi. megadtad a típust, és calloc void* -ot ad vissza, azt bele lehet tölteni warning nélkül. erre tatlálták ki a char* helyet...
majd olnap megnézem/meggondolom mire gondoltál, ha nem erre. jóéjt
- A hozzászóláshoz be kell jelentkezni
Gyors javítás:
t1_t *func (void)
{
t1_t *res = calloc(sizeof(t1_t),1);
int j;
for(j=0;j<T_SIZE;j++){
(*res)[j].c='\1';
(*res)[j].i=-1;
}
return res;
}
Igényes javítás:
typedef struct telem {
char c;
int i;
} telem;
typedef struct tstruct {
telem v[T_SIZE];
} tstruct;
tstruct *func (void)
{
tstruct *res = calloc (sizeof (tstruct), 1);
int j;
for (j=0; j<T_SIZE; j++) {
res->v[j].c='\1';
res->v[j].i=-1;
}
return res;
}
Magyarul: lehetőleg ne használjunk összetett típusnak egy puszta tömböt, hanem ágyazzuk be egy struktúrába, például azért, hogy a fordító észrevegye az ilyesfajta hibákat.
- A hozzászóláshoz be kell jelentkezni