Bus error:10 przy zwalnianiu obiektu klasy vector

Odpowiedz Nowy wątek
2015-06-02 18:58
0

Niestety mam problem w kodzie, gdyż w momencie kiedy zwalniam wskaźnik na obiekt vector<char*> pojawia się Bus error: 10
Kiedy nie usuwam obiektu wszystko jest ok. Wielokrotnie pisałem podobny kod i nigdy nie miałem tego typu problemu :(


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <dirent.h>
#include <sys/stat.h>

#define DEBUG
#ifdef DEBUG
#define ECHOD(NAME, VALUE) cout << "*** DEBUG ***" << " NR LINE: " << __LINE__ << " IN FUNCTION: " << __FUNCTION__ << " NAME: " << NAME << " VALUE: " << VALUE << endl;
#else
#define ECHOD(NAME, VALUE)
#endif

using namespace std;

class MCScandir;

class MCScandir {
    private:
        const char* dirpath;
        const char* filename;
        MCScandir(const char* dirpath_) : dirpath(dirpath_) {}

    public:
        void* object;
        static MCScandir& createScandir(const char* dirpath_) { dirpath_ = (dirpath_ == NULL)?"./":dirpath_; static MCScandir sd(dirpath_); return sd; }
        ~MCScandir() {}

        int scan(vector<char*> &v, int(*sd)(const MCScandir& o) = NULL);

        const char* getFilename() const { return filename; }

};

int filter(const MCScandir& o);

struct fdata {
    const char* fname;
    int fsize;
};

int main(int argc, const char* argv[]) {

    int i = 0;
    MCScandir sd = MCScandir::createScandir(argv[1]);
    vector<char*> *v = new vector<char*>;
    int(*filter_search_files)(const MCScandir& o) = &filter;
    // const char* find = "include";
    //string* find = new string("include");
    //string find("include");
    struct fdata *fnd;
    fnd->fname = "include";
    fnd->fsize = 1024;

    sd.object = (struct fdata*)fnd;
    sd.scan(*v, NULL);

    for(i = 0; i < v->size(); i++) {
        cout << (*v)[i] << endl;
        delete (*v)[i];
    }

    //delete v;

    return 0;

}

int MCScandir::scan(vector<char*> &v, int(*sd)(const MCScandir& o)) {

    DIR* dh = opendir(dirpath);
    struct dirent* d = NULL;
    char* fname = NULL;
    struct stat st;

    if(dh == NULL) {
        return -1;
    }

    while(d = readdir(dh)) {
        filename = d->d_name;
        lstat(filename, &st);
        if(S_ISDIR(st.st_mode))
            continue;

        if(sd == NULL) {
            fname = new char[strlen(filename)];
            strcpy(fname, filename);
            v.push_back(fname);
            ECHOD("NULL::fname:", fname);

        } else if(sd(*this)) {

            fname = new char[strlen(filename)];
            strcpy(fname, filename);
            v.push_back(fname);
            ECHOD("PTR_FUNC::fname", fname);
        }

    }

    closedir(dh);
    return v.size();

}

int filter(const MCScandir& o) {

    ECHOD("filename", o.getFilename())

    string line;
    int fsize = 0;
    fstream f(o.getFilename());

    if(!f.is_open()) {
        return 0;
    }

    if(o.object == NULL)
        return 0;

    f.seekg(0, ios::end);
    fsize = f.tellg();
    f.seekg(0, ios::beg);

    ECHOD("fsize", fsize)

    while(getline(f, line)) {
        if((line.find(static_cast<struct fdata*>(o.object)->fname) != string::npos) && (static_cast<struct fdata*>(o.object)->fsize > fsize)) {
            f.close();
            return 1;
        }

    }

    f.close();
    return 0;

}
edytowany 1x, ostatnio: macsurf, 2015-06-02 19:00

Pozostało 580 znaków

2015-06-02 19:24
0

tak w teorii to vector jest tablicą... dynamiczną może delete[] zadziała?


Programuje i programuje ,przychodzi człowiek "o niższej inteligencji" i rok pracy zmarnowany
To nie zadziała :) Vector jest obiektem tak więc jeśli mam tam wskaźnik na obiekty typu vector<char*> to delete uruchomi jego destruktor i tam się wysypuje. Wcześniej nie miałem wskaźnika tylko sam obiekt i destruktor oczywiście wywoływał się po wyjściu z zakresu main - efekt oczywiście ten sam :( - macsurf 2015-06-02 19:39

Pozostało 580 znaków

2015-06-02 19:27
0

delete v[i];


ale on chce usunąć wskaźnik na vector a nie element vectoru - Niikelion 2015-06-02 19:28

Pozostało 580 znaków

2015-06-02 20:00
0

swoją drogą, tworzenie vectora na stercie i dodatkowo przypisanie jego adresu do raw pointera? Życie Ci niemiłe?

Domyślnie tego nie było, zostało zrobione tylko po to aby sprawdzić gdzie jest błąd. Gdybym tego nie zrobił to bym cały czas miał Bus error :) - macsurf 2015-06-02 20:06

Pozostało 580 znaków

2015-06-02 20:14
0

No więc tak jak zmieniam kod tak aby w pętli nie była wywołana metoda size() i co .... ? Działa a wartość w zmiennej total jest dokładnie taka sama jak w v->size().
Koniec świata ;) albo jestem w matrixie ehh

    cout << "Total: " << v->size() << endl;

    for(i = 0; i < total; i++) {
        cout << (*v)[i] << endl;
        delete (*v)[i];
    }

    delete v;

Pozostało 580 znaków

2015-06-02 20:32
0

to czyszczenie pamięci nie wygląda najlepiej. Zerknij, jak alokujesz poszczególne elementy vectora:

fname = new char[strlen(filename)];
strcpy(fname, filename);
v.push_back(fname);

a jak zwalniasz ich pamięć:

 delete (*v)[i];
edytowany 1x, ostatnio: EvilOne, 2015-06-02 20:33
Sprawdziłem wszystkie adresy dodawane w push_back i te z delete. Wszystkie są takie same, brak jakichkolwiek wycieków pamięci. - macsurf 2015-06-02 20:51
zwróciłem na to uwagę, bo tworzy tablicę, a zwalnia jako zwykłą zmienną. - EvilOne 2015-06-02 20:56
Zgadza się wcześniej miałem delete[] (*v)[i] po prostu już nie wiem co należy zrobić, żeby nie było bus errora - macsurf 2015-06-02 21:36
wiesz, w zasadzie to tak powinno być. Ja na Twoim miejscu postarałbym się wyeliminować gołe wskaźniki, szczególnie utworzył ten kontener na stosie. Zamiast <char*> spróbuj zamienić na <std::string> jeśli to możliwe. - EvilOne 2015-06-02 21:54
Kontener vector na samym początku był na stosie :) Zaalokowałem go na stercie dopiero jak chciałem aby destruktor się nie odpalał :) - macsurf 2015-06-02 22:13

Pozostało 580 znaków

2015-06-02 21:58
0

Dobra problem już rozwiązałem. Głupie przeoczenie :/
Chodziło o strukturę, była zadeklarowana jako wskaźnik na strukturę :/ Tylko sama deklaracja ehh
Teraz jest już OK!

struct fdata fnd;
fnd.fname = "include";
fnd.fsize = 1024;
sd.object = (struct fdata*)&fnd;
edytowany 1x, ostatnio: macsurf, 2015-06-02 21:58

Pozostało 580 znaków

2015-06-02 22:05
0

Co ciekawe na OS X nie buntował się przy strukturze i to mnie zmyliło ale już na Linux Mint jak kompilowałem od razu wychwyciłem problem, tam na dzień dobry było segmentation fault przy strukturze, która nie było zdefiniowana ( sama deklaracja ).

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0