Mi lehet ezzel?

 ( Anonymous | 2004. február 16., hétfő - 8:43 )

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Sziasztok!

Köszi szépen a választ és mindenkinek a segítséget!!! Most már mûködik!

Hi!
Tom

Írtam egy funkciót, ami részeket olvas be a fájlból id alapján.
Ha a main-bõl hívom, megy tökéletesen, de ha egy másik funkcióból, akkor segmentation fault.

Mi lehet ennek a baja? Memória?

[code:1:c8aa3ace95]

char* ReadMessage(const char* filename, char* id) {

char *buffer, *result, *tmp;
FILE *file = fopen(filename,"r");
int i, pos;

struct stat fileinfo;
stat(filename,&fileinfo);

if(errno != 0) {
PrintErrorMessage(strerror(errno),filename,2);
endwin(); exit(1);
}

tmp = (char*) malloc(sizeof(char)*2);
buffer = (char*) malloc(fileinfo.st_size + 1);
result = (char*) malloc(sizeof(char)*2);

fread((char*) buffer,1,fileinfo.st_size,file);

for(i = 0; i != strlen(buffer); i++) {
if(buffer[i] == id[0] && buffer[i+1] == id[1]) {
pos = i + strlen(id); break;
}
} i = 0;

while(buffer[pos] != id[0] && buffer[pos+1] != id[1]) {
tmp[0] = buffer[pos];
tmp[1] = '\0';
if(strcspn(tmp,"\n\t\r\v") == 1) {
result[i] = buffer[pos];
} else {
result[i] = ' ';
}
result = (char*) realloc(result,i + 1);
pos++; i++;

}

result[i] = '\0';

fclose(file); free(buffer); free(tmp);

if(strlen(result) == 0) {
PrintErrorMessage("Invalid option file..",filename,2);
endwin(); exit(1);
}

return result;

} [/code:1:c8aa3ace95]

Az illetõ funk ahonnan hívom enélkül szintén hibátlanul mûködik.

Minden segítséget megköszönök!

Postázom a funkciót amelyben kifagy. Az is jónak tûnik, úgyhogy nem értem.

[code:1:12447af611]

int TestAccess(char* filename) {

WINDOW *win, *win_in;
PANEL *pan;
chtype ch = ' ';
char *buffer, *tmp, *buf;
int i = 0, j, k[2] = {0,0},cycle = 0;

win = newwin(12,53,5,14);
win_in = derwin(win,10,51,0,0);
pan = new_panel(win);
wbkgd(win,ch|COLOR_PAIR(1));
wbkgd(win_in,ch|COLOR_PAIR(1));
box(win,ACS_VLINE,ACS_HLINE);

curs_set(0);

tmp = (char*) malloc(sizeof(char)*2);

buffer = strdup(Readfile(filename));
FindNextSection:
j = FindInFile(filename,(cycle == 0) ? "##files##" :
"##apps and scripts##",0)+1;

while(buffer[j] != '!') {
if(buffer[j] != '\n') {
tmp[i] = buffer[j];
} else {
tmp[i] = '\0';
if(cycle == 0) {
k[0] += access(tmp,F_OK|R_OK|W_OK);
} else {
k[0] += access(tmp,X_OK);
}
k[1] += 1;
tmp = (char*) realloc(tmp,sizeof(char) + 1);
i = -1;
}
tmp = (char*) realloc(tmp,strlen(tmp) + 1);
j++; i++;
}

if(cycle == 0) {
cycle = 1; i = 0;
goto FindNextSection;
}

errno = 0; free(tmp); mvderwin(win_in,1,1);
[b] buf = ReadMessage("/mydocs/default.lng","#0");[/b]

if(k[0] != 0) {
beep();
mvwprintw(win_in,0,0,tmp);
}

update_panels(); doupdate();

while((j = getch()) != 'q') {
switch(j) {
case KEY_UP:
wscrl(win_in,1); break;
case KEY_DOWN:
wscrl(win_in,-1); break;
}
}

update_panels(); doupdate();
delwin(win); free(buffer);

endwin();
exit(1);

} [/code:1:12447af611]

Sziasztok!

Tom

A malloc nem nullázza a lefoglalt memóriát.

Köszi! Ezt nem teljesen értem, bár már máskor is hallottam.

A lefoglalt blokkot kötelezõ nullázni melõtt beleírnék?
Ezek szerint vagy calloc-ot kell használni, malloc után memset?

Köszi

Szia

Tom

Egyáltalán nem kötelező!!!

Csak annyi van, ha olvasod akkor tele lehet mindenféle szeméttel.

Amúgy te, magad is közelebb lennél a dologhoz, ha gdb-vel föltérképeznéd, hol is akad le pontosan...

Zsiráf

U.i.: Így kissé találóskérdés a dolog...

Hello

Megnéztem GDB-vel, de mivel ezt most kellett elõször használnom, nem sok mindent tudtam még vele kideríteni.
Belefordítottam a debug infot is -g-vel és utána ez jött ki:

Program received signal SIGSEGV, Segmentation fault.
0x400dac1b in free () from /lib/libc.so.6
(gdb) f
#0 0x400dac1b in free () from /lib/libc.so.6
(gdb) bt
#0 0x400dac1b in free () from /lib/libc.so.6
#1 0x400db451 in realloc () from /lib/libc.so.6
#2 0x400dafb4 in realloc () from /lib/libc.so.6
#3 0x0804ae33 in ReadMessage (filename=0x804c9c9 "/mydocs/default.lng",
id=0x804c9c6 "#0") at /proj/main.c:419
#4 0x0804b149 in TestAccess (filename=0x804d4f0 "/proj/files.lst")
at /proj/main.c:490
#5 0x0804c011 in main (argc=1, argv=0xbffffe44) at /proj/main.c:784

Ebbõl számora úgy tûnik, hogy a free hívást ami a hibát okozza nem én követtem el, különben s forrásfájlom volna megjelelölve libc.so helyett. Az összes free-t kikommenteztem a körynyéken de ugyanaz történik.

Tehát gondolom valamelyik könyvtái vagy egyéb függvény hívja a free-t.

Viszont így semmilyen info 0-as frame-rõl nincs. Nincs arg, nincsenek változók és forrás info sem.

A frame részletes infoja így néz ki (ebbõl meg egy szót sem értek -:))

Stack level 0, frame at 0xbfffd5bc:
eip = 0x400dac1b in free; saved eip 0x400db451
called by frame at 0xbfffd60c
Arglist at 0xbfffd5bc, args:
Locals at 0xbfffd5bc, Previous frame's sp is 0x0
Saved registers:
ebx at 0xbfffd5a4, ebp at 0xbfffd5bc, esi at 0xbfffd5a8, edi at 0xbfffd5ac,
eip at 0xbfffd5c0

Ha a free kapott volna valamilyen argot, akkor annak itt kéne lennie vagy info args-ra le kéne jönnie nem?

Kérlek segítsetek ezt kitalálni -:)

Köszönöm!

Tom

használj ddd
nagyon tuti

No, valami ilyet próbálj:

[code:1:79a3c3e238]gdb programod
b main
r
[/code:1:79a3c3e238]
ekkor megáll a main ()-nál. ezután (n)ext-el és (s)tep-el határold be a hiba helyét (lépkedj addig, amíg ode nem érsz, ahol hibázik. next a következő sort "átlépi", step "belelép") Lehetőleg ne a libc-ben keresd a hibát :-) valószínű a te programod bugossabb :lol:

Zsiráf

[code:1:d67f02e573]

i = 0;

while(buffer[pos] != id[0] &&

buffer[pos+1] != id[1])

{   

tmp[0] = buffer[pos];

tmp[1] = '\0';

if(strcspn(tmp,"\n\t\r\v") == 1)

{

result[i] = buffer[pos];

}

else

{

result[i] = ' ';

}   

result = (char*) realloc(result,i + 1);

pos++;

i++;

}

[/code:1:d67f02e573]

Nezzuk sorban. Az elejen:

i=0,result 2 byte-os: irod result[0]t,realloc(i,1)

Kov. iteracio:

i=1,result 1 byte-os: irod result[1]-et, es tulcimezted. Innen a malloc/free/tarsaik teljes joggal borulnak.

Erdemes debuggolas elott kiadni, hogy

'export MALLOC_CHECK_=2', igy a libc az egyszerubb malloc/free/tulcimzesi hibaknal abort-tal azonnal kiugrik (man 3 malloc).

Amugy nem rossz otlet az osszes malloc utan es free elott beirni ilyesmit (esetleg makrot definialni ra):

[code:1:d67f02e573]

x = malloc(y);

#ifdef DEBUG

fprintf(stderr, "malloc(%d) returned %p\n", y,x);

#endif

[/code:1:d67f02e573]

ill.

[code:1:d67f02e573]

#ifdef DEBUG

fprintf(stderr, "free(%p)\n", x);

#endif

free(x);

[/code:1:d67f02e573]

Egyebkent annyira azert a realloc se olcso, hogy karakterenkent nyujtogasd, szoval szvsz inkabb

szamold ki elore, hogy mennyi kell, es egyszer foglald/modositsd. Tisztabb, szarazabb erzes :)