Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New Coder
    Join Date
    May 2009
    Posts
    88
    Thanks
    4
    Thanked 4 Times in 4 Posts

    Return array from function

    Sorry to have to post this really.. but I've been looking everywhere to a solution to this problem. I wrote a function to read a file (csv) into a bidimensional array, and that works fine... only I can't get the array out XD I've tried everything I can think of, any suggestions?

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    I don't know the language you're using, so I'll assume C.
    First, make sure you've allocated up you're space. Otherwise you won't be able to return anything once the stack is popped. An array is locally declared which would put it on the stack memory - you'll need to retreive it from heap instead so use malloc or another similar allocation method.
    Next you can't return an array. You can return a pointer though, and being multi-dimensional will require a pointer to a pointer. This will get more complicated as you step through the levels and add things, so I'd probably go with a Matrix struct instead. Gets around the whole int ** return and replaces it with a MATRIX * instead, which does look nicer. Once you've written the necessary functions for it, it will be easier to find what you're looking for in the matrix as well.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #3
    New Coder
    Join Date
    May 2009
    Posts
    88
    Thanks
    4
    Thanked 4 Times in 4 Posts
    I forgot to put the language in, sorry. Yes, C++. This is the function:
    Code:
    void loadmap() {
    	string line,item;
    	int row_count;
    	int line_count;
    	ifstream map(map_file.c_str());
    	if (map.is_open()) {
    		while (!map.eof()) {
    			getline(map, line);
    			istringstream linestream(line);
    			row_count = 0;
    			while (getline (linestream, item, ',')){
    				row_count++;
    			}
    			line_count++;
    		}
    		string coords[row_count][line_count];
    		line_count = 0;
    		row_count = 0;
    		map.close();
    		ifstream map(map_file.c_str());
    		while (!map.eof()) {
    			getline(map, line);
    			istringstream linestream(line);
    			row_count = 0;
    			while (getline (linestream, item, ',')){
    				coords[row_count][line_count]=item;
    				row_count++;
    			}
    			line_count++;
    		}
    	}
    	map.close();
    }
    So I replace void at the beginning with MATRIX *? I've never used malloc before... I'll look it up. Where abouts would that fit in? Could I not just make the array global?

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    You could just globalize, though that is not exactly recommended especially with a compiled language.
    You can also take in a pointer to you're function argument or return a pointer that has been allocated.
    I don't do C++, but I assume you'll still need to allocate memory for you're pointer. I also believe that 'new' will allocate stack memory resulting in the destruction of the pointer when the function is terminated.
    C++ *may* have a built in Matrix to work with. I doubt it, though I would assume that a third party library has been built.

    In C, I'd just write a struct for it. All we care about is columns, rows and a pointer pointer to our data. Be a pain since I'd probably use a char *** to the data as a part of my data union. Probably easier to calculate than using a char ** and relying on the rows and columns to calculate the locations needed. Then you need to write all functions required to manipulate the matrix.

    So needless to say, you can't just change void to MATRIX * unless you've written it.
    You're options (assuming that C++ is the same), is to pass a pointer as an argument (or assuming an object will work as well), return an allocated pointer / object, and globalize.

    One of the C++ guys can probably give you a much better idea / solution for this. If you write you're own matrix, a class would be the best route, but I don't trust my C++ skills nearly enough to help you on that, sorry.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • Users who have thanked Fou-Lu for this post:

    satchel (06-11-2009)

  • #5
    New Coder
    Join Date
    May 2009
    Posts
    88
    Thanks
    4
    Thanked 4 Times in 4 Posts
    Thanks for your help, I'll give it a go

  • #6
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    Just as you can use an array of arrays to represent a multidimensional structure in C, you can use a vector of vectors in C++.

    Some of the advantages of this approach are that you can return a vector because it knows what size it is and doesn't create an ambiguous situation like returning a pointer to an array, and that you don't need to know what the final dimensions of the structure will be when you instantiate it, so you can add to it as you go along. This means that you can condense your function to work using only one loop through the file.

    I didn't feel like rewriting your CSV thing, but here is an example of the vector-specific stuff you would have to change to use this approach:

    Code:
    #include <vector>
    
    typedef std::vector<std::string> StringList;
    typedef std::vector<StringList> StringMatrix;
    
    StringMatrix loadmap()
    {
    	StringMatrix rv; // size unknown, thus far
    	for (size_t i = 0; i < 10; ++i)
    	{
    		rv.push_back(StringList()); // add a row
    		for (char j = 'A'; j <= 'Z'; ++j)
    			rv[i].push_back(std::string(1, j)); // add a column
    	}
    	return rv;
    }
    
    int main()
    {
    	StringMatrix mat = loadmap();
    	// Use iterators to traverse the results without running off the end of any rows or columns
    	for (StringMatrix::const_iterator row = mat.begin(); row != mat.end(); ++row)
    	{
    		for (StringList::const_iterator col = row->begin(); col != row->end(); ++col)
    			std::cout << *col;
    		std::cout << "\n";
    	}
    }
    Which just prints the alphabet 10 times.

    (If you're not familiar with typedef, it just creates an alias of a type. You could, if you wanted, change every instance of StringList to std::vector<std::string> and every instance of StringMatrix to std::vector<std::vector<std:: string> > without impacting the functionality of the program.)
    Last edited by ralph l mayo; 06-12-2009 at 01:53 AM.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •