Segmentation fault error

Hi,i'm trying to list all folders in "Downloads" directory including subfolders.

Here is my code,it shows me "Segmentation fault" error when i run it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
vector<string> queuedFolders;

void DIR_GetFolders(char dir[])
{
    unsigned char isFolder = 0x4;
    DIR * f;
    struct dirent *folder;
    f = opendir(dir);
    if (f != NULL)
    {
        while (folder = readdir(f))
        {
            if (folder->d_type == isFolder && strcmp(folder->d_name,".") && strcmp(folder->d_name,".."))
            {
                char a[sizeof(dir)/sizeof(char) + 1 + sizeof(folder->d_name)/sizeof(char)] = "";
                strcat(a,dir);
                strcat(a,"/");
                strcat(a,folder->d_name);
                queuedFolders.push_back(a);
            }
        }
    }
}

int main()
{

    char* HOMEDIR = getenv("HOME");
    char* CURFOLDER = HOMEDIR;
    strcat(CURFOLDER,"/Downloads");

    DIR_GetFolders(CURFOLDER);

    for(vector<string>::iterator i = queuedFolders.begin(); i != queuedFolders.end(); i++)
    {
        char * a;
        string b = *i;
        a = new char[b.length() + 1];
        strcpy(a, b.c_str());
        DIR_GetFolders(a);
    }

    return EXIT_SUCCESS;
}
Line 15. sizeof(dir) and sizeof(folder->d_name) do not do what you think they do. sizeof() is not a synonym for strlen(). And you cannot use strlen() in a constant expression, so the whole line needs to be rewritten.

My advice: use std::string instead.
+1 PanGalactic

use std::string
+256 PanGalactic

And what bugs me is why you were switching between chars and strings. After all, see line 34.

http://cplusplus.com/reference/string/string/append/

-Albatross

Thanks for replies. Yeah,line 15 making char array instead of string was stupid.
However, for opendir() I have to pass char array,because when I pass string to it,compiler shows me error.

My code now looks like this:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
vector<string> queuedFolders;

void DIR_GetFolders(string dir)
{
    unsigned char isFolder = 0x4;
    DIR * f;
    struct dirent *folder;
    char slova[dir.length() + 1]; // ============ String to char array, will this work ?
    strcpy(slova, dir.c_str());
    f = opendir(slova);
    if (f != NULL)
    {
        while (folder = readdir(f))
        {
            if (folder->d_type == isFolder && strcmp(folder->d_name,".") && strcmp(folder->d_name,".."))
            {
                string a = "";
                a += dir;
                a += "/";
                a += folder->d_name;
                queuedFolders.push_back(a);
            }
        }
    }
}

int main()
{

    char* HOMEDIR = getenv("HOME");
    char* CURFOLDER = HOMEDIR;
    strcat(CURFOLDER,"/Downloads");

    DIR_GetFolders(CURFOLDER);

    for (vector<string>::iterator I = queuedFolders.begin() ; I != queuedFolders.end( ) ; I++ )
    {
        char slova[*I.length()+1]; //Here is error for this line: /home/igor/Documents/CodeBlocks/OOP/main.cpp|77|error: ‘class __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >’ has no member named ‘length’|
        strcpy(slova,*I.c_str); // /home/igor/Documents/CodeBlocks/OOP/main.cpp|78|error: ‘slova’ was not declared in this scope| + again the same error as for line above
        DIR_GetFolders(slova);
    }

    return EXIT_SUCCESS;
}
1
2
3
    char* HOMEDIR = getenv("HOME");
    char* CURFOLDER = HOMEDIR;
    strcat(CURFOLDER,"/Downloads");

You're writing into oblivion. You shouldn't write into the buffer returned by getenv(). Use strings for strings. It'll save you from yourself in the long run.
1
2
3
4
    std::string CURFOLDER;
    if (const char* HOMEDIR = getenv("HOME"))
        CURFOLDER += HOMEDIR;
    CURFOLDER += "/Downloads";



Pass dir directly to opendir.
Declare variables where they're used.
DIR* f = opendir(dir.c_str());

Shouldn't you be calling closedir() when you're done?
Last edited on
Yeah,i started learning C++ some time ago and than stopped and wanted to just continue where i stopped. Didn't think i will forget so much stuff.

Anyway,the point was to find all folders and than list all files in those folders. Now i changed it a bit so it scans folders and files in the same time.

Here is the code and it works now ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
vector<string> allFiles;
vector<string> queuedFolders;

void DIR_GetFolders()
{
    unsigned char isFolder = 0x4;
    unsigned char isFile = 0x8;
    vector<string> readyFolders;

    do
    {
        readyFolders = queuedFolders;
        queuedFolders.clear();
        for (vector<string>::iterator i = readyFolders.begin(); i != readyFolders.end(); i++)
        {
            struct dirent *folder;
            string dts = *i;
            DIR * f = opendir(dts.c_str());
            if (f != NULL)
            {
                while (folder = readdir(f))
                {
                    if (folder->d_type == isFolder && strcmp(folder->d_name,".") && strcmp(folder->d_name,".."))
                    {
                        string a = dts;
                        a += "/";
                        a += folder->d_name;
                        queuedFolders.push_back(a);
                    }
                    if (folder->d_type == isFile && strcmp(folder->d_name,".") && strcmp(folder->d_name,".."))
                    {
                        string a = dts;
                        a += "/";
                        a += folder->d_name;
                        allFiles.push_back(a);
                    }
                }
                (void) closedir(f);
            }
        }
    } while (readyFolders.size() != 0);
}

int main()
{

    string HOMEDIR = getenv("HOME");
    string CURFOLDER = HOMEDIR;
    CURFOLDER += "/Downloads";

    queuedFolders.push_back(CURFOLDER);

    DIR_GetFolders();

    for (vector<string>::iterator I = allFiles.begin() ; I != allFiles.end( ) ; I++ )
    {
        cout << *I << endl;
    }

    return EXIT_SUCCESS;
}
getenv can return NULL. It otherwise seems ok.
Oh,yeah,fixed that now,thanks everyone ;)
Topic archived. No new replies allowed.