Vector iterator not dereferencable – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Vector iterator not dereferencable – C / C++ – Fórum – Programujte.comVector iterator not dereferencable – C / C++ – Fórum – Programujte.com

 

LJ10240
Stálý člen
29. 6. 2010   #1
-
0
-

Ahoj všichni,

zase potřebuji vaši pomoc... Potřebuji zjistit všechny soubory v dané složce a ve všech subdirektoriích.
Tady mám zdrojový kód, který mi nefunguje...

char appPath[MAX_PATH];

char* GetFN(char *fileName) {//spojí název zadaného souboru a cestu k programu
GetModuleFileName(NULL,appPath,MAX_PATH);
string currentDir = appPath;
size_t i = currentDir.rfind("\\", strlen(appPath));
currentDir.resize(i + 1);
currentDir.append(fileName);
ZeroMemory(appPath,strlen(appPath));
strcpy(appPath,currentDir.c_str());
return appPath;
}
bool Tie(char start[MAX_PATH]){
vector<string> vList;//sem přijdou jednotlivé soubory
vector<string>::iterator itr;

vector<string> vDirs;//sem se ukáldají složky
vector<string>::iterator itrD;
vDirs.push_back(start);/*jako první se do seznamu přidá počáteční složka,
kterou získáme z parametru této fce*/
for(itrD=vDirs.begin();itrD!=vDirs.end();itrD++){//bude procházet celý seznam složek
/*při druhém průchodu debugger vyhodí chybu (viz přílohu)*/
char mem[1024];
WIN32_FIND_DATA wfd;
HANDLE hf;
sprintf(mem, "%s*", itrD->c_str());//do "mem" se uloží např.: "C:\Program Files\*"
hf=FindFirstFile(mem, &wfd);//začneme vyhledávání souborů první sloužkou v seznamu
if(hf==INVALID_HANDLE_VALUE)
return 0;
do{
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
if(strcmp(wfd.cFileName, ".")!=0 && strcmp(wfd.cFileName, "..")!=0){
sprintf(mem, "%s%s\\", itrD->c_str(), wfd.cFileName);
vDirs.push_back(mem);/*pokud je nalezený soubor složkou,
přidáme ho do seznamu složek*/
}
}else{
sprintf(mem, "%s%s", itr->c_str(), wfd.cFileName);
vList.push_back(mem);//všechny soubory ukládáme do seznamu souborů
}
}while(FindNextFile(hf, &wfd) != 0);
FindClose(hf);
}
ofstream fout;
fout.open(GetFN("cache.tmp"), ios::out);
for(itr=vList.begin();itr!=vList.end();itr++){
fout << itr->c_str();//seznam souborů uložíme
}
fout.close();
return 1;
}


Podle mě je chyba v tom, že se ten seznam složek neustále mění... Nevím to ale určitě a už vůbec nevím, co s tím mám dělat..
Ještě jednou vás prosím, abyste mi s tím problémem pomohli...

Nahlásit jako SPAM
IP: 217.30.64.–
liborb
~ Redaktor
+18
Guru
30. 6. 2010   #2
-
0
-

Je to tím, že se seznam složek mění resp. tím, že přidáváš do vectoru nové položky. Vector je vlastně jednorozměrné pole. Když na začátku nezadáš jeho velikost (kterou ani neznáš), tak se může stát (a taky se stane), že dojde k přealokaci, takže iterátor (pointer), který ukazoval na nějakou položku následně ukazuje do ... nikam.

A jak to můžeš řešit?

Třeba tak, že vlastně znáš počet (již) vložených adresářů, které se mají projít. Můžeš tedy toto jednorozměrné pole procházet jako jednorozměrné pole :smile1: , tj. místo itrD->c_str() můžeš použít vDirs[i].c_str(), kde i je index toho for cyklu, ve kterém to procházíš. Maximum tohoto cyklu při každém přidaném adresáři zvětšíš o 1. Takže iterátor itrD úplně zahodíš.

Nahlásit jako SPAM
IP: 85.207.166.–
LJ10240
Stálý člen
30. 6. 2010   #3
-
0
-

Díky moc... Už to naštěstí funguje :)
Pro úplnost:

char appPath[MAX_PATH];

char* GetFN(char *fileName) {
GetModuleFileName(NULL,appPath,MAX_PATH);
string currentDir = appPath;
size_t i = currentDir.rfind("\\", strlen(appPath));
currentDir.resize(i + 1);
currentDir.append(fileName);
ZeroMemory(appPath,strlen(appPath));
strcpy(appPath,currentDir.c_str());
return appPath;
}
bool Tie(char start[MAX_PATH]){
vector<string> vList;
vector<string>::iterator itr;

vector<string> vDirs;
vector<string>::iterator itrD;
vDirs.push_back(start);
int maxD=1;
for(int i=0;i<maxD;i++){
char mem[1024];
WIN32_FIND_DATA wfd;
HANDLE hf;
sprintf(mem, "%s*", vDirs[i].c_str());
hf=FindFirstFile(mem, &wfd);
if(hf==INVALID_HANDLE_VALUE)
return 0;
do{
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
if(strcmp(wfd.cFileName, ".")!=0 && strcmp(wfd.cFileName, "..")!=0){
sprintf(mem, "%s%s\\", vDirs[i].c_str(), wfd.cFileName);
vDirs.push_back(mem);
maxD++;
}
}else{
sprintf(mem, "%s%s", vDirs[i].c_str(), wfd.cFileName);
vList.push_back(mem);
}
}while(FindNextFile(hf, &wfd) != 0);
FindClose(hf);
}
ofstream fout;
fout.open(GetFN("cache.tmp"), ios::out);
for(itr=vList.begin();itr!=vList.end();itr++){
fout << itr->c_str() << endl;
}
fout.close();
return 1;
}

Nahlásit jako SPAM
IP: 217.30.64.–
Palmik0
Super člen
30. 6. 2010   #4
-
0
-

Nebo, v případě že byl problém pouze v tom, že iterátory již neukazovaly tam kam by měli nebo již neukazovaly nikam, tak pokud dobře koukám (v první verzi nikde nevyužíváš random access přístupu), by jsi mohl použít std::list namísto std::vector, kde by měli iterátory "zůstat na místě" i pokud do listu něco pushneš nebo z něj naopak něco vymažeš (krom případu kdy vymažeš prvek na který ukazoval nějaký iterátor) .

Nahlásit jako SPAM
IP: 85.207.177.–
Yesterday is history. Tomorrow is a mystery. Today is a gift and that is why it's called the present.
LJ10240
Stálý člen
30. 6. 2010   #5
-
0
-

Palmik napsal:
Nebo, v případě že byl problém pouze v tom, že iterátory již neukazovaly tam kam by měli nebo již neukazovaly nikam, tak pokud dobře koukám (v první verzi nikde nevyužíváš random access přístupu), by jsi mohl použít std::list namísto std::vector, kde by měli iterátory "zůstat na místě" i pokud do listu něco pushneš nebo z něj naopak něco vymažeš (krom případu kdy vymažeš prvek na který ukazoval nějaký iterátor) .



Máš sice pravdu, nicméně random access využívat nejspíš budu, takže to nechám, jak to je... Ale díky za ochotu :)

Nahlásit jako SPAM
IP: 217.30.64.–
CZechBoY+4
Věrný člen
30. 6. 2010   #6
-
0
-

nevim jak pro subsložky ale když chceš vypsat seznam složek a souborů tak by mělo fakat ScanDir

Nahlásit jako SPAM
IP: 213.192.10.–
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, 40 hostů

Podobná vlákna

Iterátor — založil Martin Heller

C++ iterator — založil l1zard

Iterator — založil JouiBart

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ý