Before I write this, I realize there are way better ways to accomplish what I am asking, but I am JUST wondering if it is possible to do it the way I am asking.

I have a main function called system. The system has a menu and depending on input, it
calls subfunctions to do user requisted tasks.

The user will supply a file that contains some data. The first line of the data is the size of the structure in which this data is to be stored (A graph consisting of an array of singly linked lists). I would like one function to read, create and populate this array from the file, then use another function to analyze it.

The problem I am encountering is how can the other function access this structure if it is to be dynamicaly created within the first function? (therefore a temporary object)

This works fine if I combine everything in one function, I am just wondering if it is somehow possible to make this structure reusable once one function has built it (remember, it is not part of the system because the size is not known until the user supplies the file). I am guessing one solution is for the first function to return this structure? Is there an easier way? This solution would require a complicated copy constructor.

Thanks.

PS. I would like to thank Vijay for helping me out with this (school) project so far.

Recommended Answers

All 7 Replies

Actually, you are doing things the Right Way. Five stars for you for using your head.

Things are only temporary if you don't plan to use them long. In C++, you can pass things around easily enough and extend their life beyond normal even.

Local variables only live as long as the function they are declared in. But stuff you allocate on the heap is global. You only use local variables to play with it.

Here's a fun program you can play with:

#include <iostream>
#include <sstream>
#include <cctype>
using namespace std;

struct node {
  string name;
  int    age;
  node*  next;
  };

node *get_list() {
  node *first = NULL;
  node *current;
  string name, s;
  do {
    cout << "Enter a name: ";
    getline( cin, name );
    cout << "Enter " << name << "'s age: ";
    getline( cin, s );

    if (first == NULL) first = current = new node;
    else {
      current = current->next = new node;  // pay attention here!
      current->next = NULL;
      }
    current->name = name;
    if (!(stringstream( s ) >> current->age)) current->age = 0;

    cout << "More (y/n)? ";
    getline( cin, s );
  } while (toupper( s[ 0 ] ) != 'N');

  return first;
  }

void print_oldest( node *list ) {
  node *oldest = list;
  for (; list != NULL; list = list->next)
    if (list->age > oldest->age) oldest = list;
  if (oldest != NULL)
    cout << oldest->name << " is the oldest.\n";
  }

node *delete_list( node *list ) {
  node *n;
  while (list != NULL) {
    n = list;
    list = list->next;
    delete n;
    }
  return NULL;
  }

int main() {
  node *list = get_list();
  print_oldest( list );
  list = delete_list( list );
  }

You can use type caste to convert it.

/me re-reads the first post

Ah, just use new to create an array big enough to hold the head of each linked list. node **listarray = new node*[ number_of_lists ]; Then return listarray.

Hope this helps.

commented: Very helpful replies. +1

Thanks Duoas, I didn't realize this was possible. I thought the same applied as with local variables.

So it is not possible to return a pointer to the graph then? I would return an array of pointers with elements of the graph?

Here is my graph:

template <typename T>
class Graph {
      
      public:
             explicit Graph ( int size ) : SIZE (size), datar( new SinglyLinkedList<T> [size] ) {}
             ~Graph() { delete [] datar; }
             Node<T> *find(T);
             bool AddVertex(T);
             bool AddEdge(T, T);
             Node<T>* getList (int);
             
      private:
              const int SIZE;
              SinglyLinkedList<T> * datar;
              
              };

So why can't you do:

template <typename T>
Graph<T> *get_data() {
  Graph<T> *result = new Graph<T>;
  // fill graph from file here
  return result;
  }

It is the same as returning a pointer to anything else you dynamically allocate.

Thank you Duoas, you have been very helpful.

I chose not to do it that way initially because I wanted to keep my Graph function nice and clean, but I do see the advantage in doing it that way. I am now more confident in passing complex (to me, anyway) structures around!

Glad to be of help. Just don't forget to delete things when you are done with them.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.