Proč padá funkce po realloc? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Proč padá funkce po realloc? – C / C++ – Fórum – Programujte.comProč padá funkce po realloc? – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
oxidián0
Věrný člen
12. 3. 2015   #1
-
0
-

   

/* Allocates buffer and reads data

size -1 to read complete file

First time called it reads only header.
Second time called it reads the rest of the file.
*/
size_t getFileData(char * filename,
                 unsigned char ** buffer,
                 uint32_t offset,
                 size_t size){
    static FILE* fp;
    bool finish;
    // If already opened skip
    if (!fp){
        fp = fopen(filename, "r");
        if( fp == NULL )
            {
            printf("Cannot open file %s",filename);
            return -3;
            }
        finish=0;
    }
    else
    if (offset == -2)
        fclose(fp);
    else
        finish=1;

    if ( offset==0){ // allocation for header
        *buffer = malloc(size);
        memset( *buffer, '\0', size);
        }
    else
      if (size==-1)
        {
        size = get_fsize(fp, 0L);
        *buffer = realloc(*buffer, size);
        memset( *buffer, '\0', 1);
        // memset( *buffer, '\0', size-offset);
        // fseek ( fp , offset , SEEK_SET );
        }

  fread(*buffer, 1, size-offset, fp);
  if (finish)
    fclose(fp); // the file is auto-closed on second call
  return size;
}

Užití...

unsigned char * buffer;
getFileData(filename, &buffer, 0, header_est_size); // read 56 bytes header

... // proccess header
getFileData(filename, &buffer, h.header_size, -1); // read rest of the file

Alokace poprvé se povedla, hlavičku jsem načetl a zpracoval. Pak spouštím podruhé a spadne to v druhé větvi if na memset( *buffer, '\0', 1);
Těsně před tím než to krachne (proměnné uvnitř funkce):

size:   2115025

offset: 56

*buffer: neiniciováno... 0xab <repeats 7x> 0x0 <repeats 8x>

Už mě nenapadá co by mohlo být špatně. Vše vypadá jako že se to nepovedlo reallocovat, ale proč?

Nahlásit jako SPAM
IP: 78.45.199.–
Reklama
Reklama
KIIV+42
God of flame
12. 3. 2015   #2
-
0
-

Uzasny, ze nam sem hodis obsah *buffer. Skoda jen, ze je to naprosto totalne nahovno. Co sem hodit ten pointer!!!!!

Pak cirou nahodou muze nastavovat errno.

Muzes taky pouzit valgrind (teda nemuzes, pokud nejsi na linuxu) - nicmene mi to zadnou chybu nevyhodilo.

Pak je uzasny, ze znas klicove slovo static - jenze si zminoval, ze chces pouzivat vic vlaken. Tim sis prave pod sebou urezal vetev, na ktery stojis.

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
12. 3. 2015   #3
-
0
-

žádnou chybu nenastavuje

buffer (unsigned char **) 0x22ff30

*buffer: Cannot access memory at address 0x0

testuju ve Windows XP na x86

Nahlásit jako SPAM
IP: 78.45.199.–
PiranhaGreg0
Stálý člen
12. 3. 2015   #4
-
+1
-
Zajímavé

Oxidiáne, nauč se radši pořádně základy a pak se teprve pouštěj do něčeho složitějšího. Ty tvoje jazykový konstrukce jsou fakt perly. Zrovna u Cčka je IMHO důležitý, aby jsi věděl co jak přesně funguje, jinak se z těch bugů nevyhrabeš.

A vlákna si nech na později. Vyvarovat se časově závislým chybám je někdy oříšek i pro zkušeného programátora a věř mi, že ty by jsi jich tam nasekal požehnaně. Takovou multivláknovou aplikaci pak prakticky nejde debugovat.

Jinak také doporučuji ten Valgrind. A kompilovat (na gcc) s -Wall -pedantic. Jakmile ti něco z toho zahlásí warning, něco je na 99% špatně a je potřeba to hned řešit...

Nahlásit jako SPAM
IP: 109.81.210.–
KIIV+42
God of flame
12. 3. 2015   #5
-
0
-

a address 0x0 je null pointer.. to je tak, kdyz vubec nekontrolujes, co se z toho reallocu a mallocu vratilo

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
12. 3. 2015   #6
-
0
-

No nevím, ale vzpomínám si že jsem to kontroloval a dával tam hlášku že se realloc nezdařila. Ale teď to tam není tak už nevím co jsem s tím dělal. Proč ale je null pointer? Size přece musí být dostatečný.

Nahlásit jako SPAM
IP: 78.45.199.–
vitamin+8
Grafoman
12. 3. 2015   #7
-
0
-

#6 oxidián
Preco je parameter buffer dvojity pointer?

Preco porovnavas unsigned cisla (size_t, uint32_t) so zapornymi cislami?

Nahlásit jako SPAM
IP: 95.105.229.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
oxidián0
Věrný člen
12. 3. 2015   #8
-
0
-

Dvojitý pointer tam je protože potřebuju ten buffer sdílet mimo funkci getFileData.

Odpozoroval jsem že ten pointer který chci reallocovat nemá stejnou adresu jako poprvé, takže jsem ho někde přepsal.

Příčina: během zpracovávání buffer (hlavičky) se posunul ukazatel. Realloc neukazuje na začátek buffer.

Vyřešeno.

Nahlásit jako SPAM
IP: 78.45.199.–
ondrej39+1
Věrný člen
13. 3. 2015   #9
-
0
-

#8 oxidián
A i přes to, že to chceš sdílet je dvojitý ukazatel k ničemu. Jak psal Piranha a vlastně už párkrát i ostatní, nauč se základy.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
KIIV+42
God of flame
13. 3. 2015   #10
-
0
-

#9 ondrej39
Na druhou stranu, kdyz si na tomhle priserne vymlati zuby, tak to uceni se zakladu bude mit uplne jinou efektivitu. Mozna to asi delam jen ja, ze kdyz si procitam neco o programovani, tak rovnou premyslim na co by se to dalo dobre pouzit a tak.

A kdyz chce holt delat alokace uvnitr funkci, tak jinak pointer ven nedostane (pokud chce vracet zrovna size jako navratovou hodnotu).

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
13. 3. 2015   #11
-
0
-

Odpozoroval jsem že ten pointer který chci reallocovat nemá stejnou adresu jako poprvé, takže jsem ho někde přepsal.

Pokud alokuji paměť, dbám na to, aby ukazatel na ni zůstal nedotčený. Často pak při práci s touto pamětí používám kopii ukazatele. Dokud mám ukazatel na paměť co jsem alokoval, mohu ji realokovat nebo uvolnit.

Ještě pozor u realloc. Po realokování se může ukazatel změnit. Podrobnosti najdeš v dokumentaci funkce.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:429:d30...–
ondrej39+1
Věrný člen
13. 3. 2015   #12
-
0
-

#10 KIIV
Pointer ven nedostane, ale nedává v tomto případě větší smysl dostat ven prostě buffer, aby nemusel všude jinde definovat pointer na pointer na char?

Pointer na buffer si může v outer scope této funkce už udělat kdy bude chtít, myslím si, že je rozumnější funkci pouze předat "strukturu", pole, u něhož bude probíhat změna.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
KIIV+42
God of flame
13. 3. 2015   #13
-
0
-

#12 ondrej39
vetsi smysl dava mit buffer na hlavicku a pak promenlivy buffer na data. Z hlavicek vykuta velikost, pripravi buffer a preda funkci k nacteni. To samy ten static file descriptor.

Uz takhle si clovek musi davat furt pozor, ze vetsina standardnich funkci je zmrsena tak, ze se nedaj pouzit ve vice vlaknech (a rovnou pouzivat ty reentratni verze). Aspon ze errno funguje pro kazdy vlakno zvlast.

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Věrný člen
13. 3. 2015   #14
-
0
-

#9 ondrej39
Já jsem ho odstranil a nefungovalo mi to, takže to nechám tak jak to je. Jak sis jistě všiml vracím size takže jiná cesta není.

Nahlásit jako SPAM
IP: 78.45.199.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 113 hostů

Podobná vlákna

Proč to padá ? — založil Lukáš Vašek

Proč funkce zamrzá? — založil Mutagen

Proč se mi nevolá funkce? — založil delicacyy

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý