return the dang array! ...please?

i have created a function that will get data out of a file and put it into an array... the only problem is returning the dam thing. Because an array is of type 'memory', it wount let me return it. Is it possible for me to do this? Here is the code:

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
string get_backup_dat(string bkpname)
{
    string files[1000][1000];
    int sizes[1000];
    int d, dim = -1, dim2 = -1;
    string line, dir;
    bkpname = ("\\backups\\" + bkpname + "\\");
    d = check_dir(bkpname);
    if(d == 0)
    {
        cls();
        _cl();
        return "";
    }
    ifstream b;
    b.open(bkpname.c_str(), ios::in);
    while(b.good())
    {
        dim2 = -1;
        dim++;
        dim2++;
        getline(b, line);
        dir = line;
        files[dim][0] = dir;
        line.clear();
        while(dir != line)
        {
            dim2++;
            getline(b, line);
            if(line == dir)
            {
                break;
            }
            files[dim][dim2] = line;
        }
        sizes[dim] = dim2;
    }
    b.close();
    ofstream s;
    s.open("sizes.dat", ios::out);
    for(int x = 0; x <= dim; x++)
    {
        s<< sizes[x]<< " ";
    }
    s.close();
    return files;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int get_sizes()
{
    int sizes[1000];
    int num, x = -1;
    ifstream sz;
    sz.open("sizes.dat", ios::in);
    while(sz.good())
    {
        x++;
        sz>> num;
        sizes[x] = num;
    }
    sz.close();
    remove("sizes.dat");
    return sizes;
}


Thank you in advance.
Last edited on
Yeah there is a way you could do this, but I would definitely recommend looking at the resizable array types in the Standard Template Library (std::vector and the like). Anyway, fixing the second function could be done by returning a pointer to an int, and allocating the array dynamically using malloc.

1
2
3
4
5
6
int* get_sizes()
{
    int* sizes = (int*)malloc(sizeof(int) * 1000);
   // your other code
   return sizes;
}


Changing the first function is a bit more complicated since you have a two dimensional array. In this case you will need to return a pointer to a pointer to a string.

1
2
3
4
5
6
7
8
9
10
string** get_backup_dat(string bkpname)
{
    string** files = (string**)malloc(sizeof(string*) * 1000);
    for (int i = 0; i < 1000; ++i)
   {
        files[i] = (string*)malloc(sizeof(string) * 1000);
   }
   //the rest of your code
   return files;
}


Also you _must_ free this memory afterwards, or else you will have memory leaks. In the case of 1000000 strings this could be a significant chunk of memory. This is kinda hacky and dangerous but should work

well, here's the structure:
0 1 2 3 4 ...
0 directory file file file file etc...
1 directory file file file file etc...
2 directory file file file file etc...
3 directory file file file file etc...
4 directory file file file file etc...
5 directory file file file file etc...
6 directory file file file file etc...
.
.
.


I know that if I have 10 folders, with 5 folders and 20 files inside (each) that is 50 directories, and 200 files pertaining to each directory. then we add the files inside those 50 directories. let's say we have 5 files in each directory. That's another 550 (we have these folders in each of our 10 folders). That is 750 files, and 60 directories. The way I see it, im just giving some slack so the user doesnt run out of riegn. And btw, I do delete the arrays (delete [] arrayhandle) in another function.

1 question though:

if I delete the arrays in this function, will it delete the arrays globally (or throughout the entire program?)?
You could just use a void function and put an array in it. Then you could change the array instead of trying to return it. As far as I know, you can only put an array into an array, which is completely pointless if you can just change the data in an array by passing it to a function, but this may be just a little out of my league from what little I've seen.
@Grex2595
You could just use a void function and put an array in it.

you mean i could pass the array to the void function as an argument, and the function would change the array accordingly?

As far as I know, you can only put an array into an array

That doesnt make any sense at all.

this may be just a little out of my league

it isnt.

BTW:

Im not a beginner, but i my experience with arrays and their 'memory' proporties is somewhat limited. I usually use vectors, but this is a complicated data structure so i am forced to use an array, or I will be making a really complex parsing function, or a lot of vectors. Either way, knowing how to use arrays like this can't hurt, and if anyhting it will benefit me. I also taught myself C++, so you may just be seeing the way I write it.
Last edited on
I usually use vectors, but this is a complicated data structure so i am forced to use an array, or I will be making a really complex parsing function, or a lot of vectors.


What makes you think that?

It isn't clear what you're hoping to accomplish with your first function, so it's hard to recommend a solution. It looks like you may be trying to extract data from a file, but skip duplicate lines in the file (but unless those files only have duplicates in very specific places your algorithm won't work, so I assume you're doing something else.)

sizes appears to hold the number of lines you've stored in a particular dimension of file. Why you then write that to file is confusing to me as that info is sort of useless without the corresponding array.






Last edited on
oh, im so sorry. I should tell you the data structure I'm useing. The function you are looking at reads and extracts data in (what I believe to be) and organized way. I decided to use lines instead of characters (sooo much easier to parse) and a repeat line of the 1st directory marks the end of that directory, then the next line (if there is one) starts the next directory.

It goes something like this:

[directory 1]
file
file
file
...
[directory 1]
[directory 2]
file
etc...
[directory 2]

it then sorts the data into an array, like so:

1
2
3
    __1___________2________3________4.....
1  |directory 1___file___file___etc...
2  |directory 2___file___file___etc...


This way it makes it so all i have to do to 'backup' the data is create 2 for() loops.
Last edited on
Perhaps something like the following would serve.

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
std::deque<std::vector<std::string> > get_backup_dat(std::string bkpname)
{
	bkpname = ("/backups/"+bkpname+"/") ;
	/*
	if ( 0 == check_dir(bkpname) )
	{
	cls() ;
	_cl() ;
	return ;
	}
	*/

	std::vector<unsigned> entriesPerDirectory ;

	std::ifstream backupList(bkpname.c_str()) ;
	std::string directoryName ;
	std::deque<std::vector<std::string> > fileDirectory ;

	while( std::getline(backupList, directoryName) )
	{
		unsigned nEntries = 1 ;
		std::vector<std::string> list ;
		list.reserve(256) ;   // set this to a reasonable number for your data set.
		list.push_back(directoryName) ;

		std::string fileName ;
		while ( std::getline(backupList, fileName) && fileName != directoryName )
		{
			++nEntries ;
			list.push_back(fileName) ;
		}

		// should probably check state of backupList here and handle any error.

		entriesPerDirectory.push_back(nEntries) ;

		// swap idiom avoids unnecessary copying.  If you have a compiler that supports
		// move semantics this would be better written as: fileDirectory.emplace_back(std::move(list));
		fileDirectory.resize(fileDirectory.size()+1) ;
		fileDirectory.back().swap(list) ;
	}

	std::ofstream numEntriesFile("sizes.dat") ;
	for ( unsigned i=0; i < entriesPerDirectory.size(); ++i )
		numEntriesFile << entriesPerDirectory[i] << ' ' ;

	return fileDirectory ;
}
nah that's alright. I decided to revamp the whole dam thing. Took 5 hours of rigorous testing, but i got it down. I switched to vectors and tomorrow im going to write a safe-gaurd against a the possibility of too many directories (if you want to keep them together, you have to put them in named folders. I wrote a vector that will name the folders containing the backups accordingly, but they are limited from a-z) and a bad call. It's actually pretty sweet. You set up your backup, decide if you want to save it, and if you save it, all you have to do next time you want to back up the same set of files is press a button.

EDIT1:

I did it. I made it parse all the directories. When it backs your files up, the origional names transfer over to the backup (spaces are removed, i made it parse them out). So, now you can put humpty dumpty back together again should you need to. :)
Last edited on
Topic archived. No new replies allowed.