Globální proměnná + přidělení paměti - malloc bufferu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Globální proměnná + přidělení paměti - malloc bufferu – C / C++ – Fórum – Programujte.comGlobální proměnná + přidělení paměti - malloc bufferu – C / C++ – Fórum – Programujte.com

 

oxidián0
Grafoman
30. 1. 2015   #1
-
0
-

V souboru main.c mám:

extern unsigned char * image_buffer; // Final image

V includovaném souboru soubor.h mám:

unsigned char * image_buffer; // Final image

(jestli to chápu správně tak jsou to dvě nezávislé proměnné, protože ten druhý buffer platí jen pro includovaný soubor (soubor.c a soubor.h ) a funkce pro čtení a zápis do souboru v něm .

mám ale dvě verze toho souboru.c a souboru.h - jedna je původní funkční, druhá je editovaná a nefunkční, ačkoliv způsob deklarace obrazového bufferu je v obou verzích stejný.

Tak se ptám - když dám do projektu původní verzi soubor.c a soubor.h

spouštím z mainu:

read_JPEG_file_rgb2hsv(filename1);

write_JPEG_file(filename2, 95);

soubor se načte a zapíše (změněný). Takže funguje.

Když dám ale do projektu ten novější soubor.c a soubor.h tak mi to v read chybně přidělí paměť bufferu

image_buffer = (unsigned char*) malloc( row_stride_len*cinfo.output_height ); // globální buffer - nezměněno!

V panelu watch vidím: (unsigned char *) 0x6f0020 ""

Měl bych správně vidět nějaké znaky abych věděl, že se inicioval... např. (unsigned char *) 0x6f0020 "ěšč+ěšuhiabrfýě+bšdzěgš+ě;s6" edit: není to pravda, znaky se oběví až po memcpy(image_buffer+counter, rows_buffer[0], raw_size);

no a dále to samozřejmě nefunguje, když načítám data ze souboru po řádcích pomocí smyčky while a ukládám je do toho bufferu

// inside reading loop:

image_buffer[counter+t]=(char)H;
image_buffer[counter+t+1]=(char)S;
image_buffer[counter+t+2]=(char)V;

tak v bufferu bude jen (unsigned char *) 0x6f0020 "A"

tak je to chyba allokace paměti, chyba globální deklarace nebo chyba uvnitř čtecí smyčky?

Ještě přikládám kód který je přímo uvnitř smyčky (konverze RGB2HSV v rámci načítání dat ze souboru jpeg):

http://paste.ofcode.org/TQZRyKfThiyncghdrLeUH6

Pokud je to globální deklarací tak nechápu kde je chyba protože mi to nedává smysl.

:

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
30. 1. 2015   #2
-
0
-

dela se to presne opacne:  s extern do include (a vsude tam, kde tu globalni promennou chces mit dostupnou)

a v jednom z .c souboru musi byt definovana bez extern (extern znamena, ze je to jen deklarace - ze bude definovana nekde jinde - a pokud neni, tak ti to pri linkovani vyhodi chybu)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
30. 1. 2015   #3
-
0
-

Já to tak předtím dělal a nefungovalo to. Když jsem to udělal takhle v té původní verzi tak to funguje v původní verzi. A tak mi to vysvětli jak je možné že to vůbec funguje ve starší verzi. Pro rekompilaci používám codeblocks ctrl+f11 takže ze starých souborů to být nemůže.

Chyba odhalena, viz nové vlákno

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
30. 1. 2015   #4
-
0
-

Z main.c jsem odstranil:

// extern unsigned char * image_buffer; // Final image
...

int main (){
    unsigned char * image_buffer;
...
    read_JPEG_file_rgb2hsv(filename1, image_buffer);
    write_JPEG_file(filename2, 95, image_buffer);
}

Funkce jsem deklaroval:

int read_JPEG_file_rgb2hsv(char * filename, unsigned char * image_buffer);
void write_JPEG_file_rgb2hsv(char * filename, int quality, unsigned char * image_buffer);

V souboru mi to krachne na řádku:

(void) jpeg_write_scanlines(&cinfo, row_pointers, 1);

Proměnná row_pointers[0]: 0x40904592 <Address 0x40904592 out of bounds>

row_pointers[0] = & image_buffer[cinfo.next_scanline * row_stride_len];

image_buffer: (unsigned char *) 0x402370 <__do_global_dtors> "\241\f0@"

Co to znamená a jak chybu odstranit?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
31. 1. 2015   #5
-
0
-

#4 oxidián
tezko rict, asi spatnej pointer

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
31. 1. 2015   #6
-
0
-

No a kdybych chtěl přidat &

read_JPEG_file_rgb2hsv(filename1, &image_buffer);


tak dostanu hlášku:

main.c|48|warning: passing argument 2 of 'read_JPEG_file_rgb2hsv' from incompatible pointer type [enabled by default]|

Prostě nevím jak to pole tam mám dostat. Když dávám image_buffer tak by to mělo teoreticky stačit, protože nepřesouvám celý zásobník, jen jeho pointer, ale vím že v praxi se často používá & ale proě když v deklaraci je * ?

Stejný problém s globální proměnnou jsem řešil ještě než jsem zkoušel použít ty globální proměnné. Bez globálbích proměnných mi to prostě nejde a teď už ani s globálníma.

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
31. 1. 2015   #7
-
0
-

no jestli tam mas jen: 

    unsigned char * image_buffer;
...
    read_JPEG_file_rgb2hsv(filename1, image_buffer);
    write_JPEG_file(filename2, 95, image_buffer);

tak se ani moc nedivim, ze ti to nefunguje.. ten buffer by to chtelo hlavne taky alokovat

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
31. 1. 2015   #8
-
0
-

On se alokuje uvnitř funkce na čtení, ale to je asi ten problém protože to nejsou stejné proměnné. Ta proměnná uvnitř funkce je vlastně lokální, tudíž po ukončení funkce zanikne. Takže bych měl asi alokovat paměť zvenčí, ale to udělat nemůžu protože neznám souřadnice. Možná by stačilo uvnitř deklarace argumentu funkce uvést global unsigned * char?

Funkce na čtení nejdříve otevře soubor, nastaví parametry ke čtení pak dekomprimuje a přečte hlavičku a teprve potom jsou přístupné data o souboru. Mám teda vytvořit samostatnou funkci která vrátí rozměry obrázku a nebude provádět dekompresi? To zní logicky, že?

Případně ve funkci main nejdříve deklarovat objekt cinfo s informacemi o souboru, pak ten objekt předat do funkce která iniciuje a vyplní ten objekt, pak to předám v referencí &cinfo. Jo a tím mám ty rozměry obrazu a mohu ten objekt použít znova, aniž bych to musel znova dekodovat. Vytvořím tedy asi funkci, která ten soubor nejdříve připraví pro otevření a předá potřebné objekty do scopu mainu, pak použiju tu funkci na čtení s tím, že do ní referencí předám objekt cinfo.

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
31. 1. 2015   #9
-
0
-

pak musis funkcim predavat adresu, kde ten pointer lezi (to si odhadl dobre na  &image_buffer)

a pak zmenit funkce, aby cekaly  unsigned char ** buff  (tedy jen ty, ktery to muzou zmenit)...  samozrejme se pak musi pouzivat jinej pristup:  *buff   kde bude pointer na zacatek bufferu,  (*buff)[x]  kde jsou jednotlivy polozky (nebo muzes pouzit i  buff[0][x]), akorat bacha - kdyz zmenis pointer v *buff, tak se zmeni i vne funkce

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
31. 1. 2015   #10
-
0
-

A jak mám vyřešit toto?

  rows_buffer = (*cinfo.mem->alloc_sarray)
                ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride_len, 1);

To první hádám  (**cinfo.mem->alloc_sarray) ale nevím jak s tím druhým &cinfo. Mám dát &*cinfo?

A taky mám problém s tímto:

cinfo.err = jpeg_std_error(&jerr.pub);


Když dám *info.err tak dostanu hlášku:

error: request for member 'err' in something not a structure or union|

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
31. 1. 2015   #11
-
0
-

Chyby jsem vyřešil a zbývá mi jediná:

GLOBAL(int)
int JPEG_read_file_rgb2hsv( unsigned char ** image_buffer, struct jpeg_decompress_struct * cDecompresInfo)

two or more data types in declaration specifiers|

 

Vyřešeno - chce abych odstranil GLOBAL(int)

JPEG_read_file_rgb2hsv(&cinfo, &image_buffer);

Znamená, že mám o jeden argument více v definici funkce.

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
31. 1. 2015   #12
-
0
-

http://paste.ofcode.org/jC5TXVGqKJVDeu9xwr3nTr

Ještě tady mi to krachuje

(void) jpeg_finish_decompress(&*cDecompresInfo); // Finish decompression, no errors possible


Jak to opravit?

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, 18 hostů

Moderátoři diskuze

 

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