-1

I'm new to C/C++ and pointers are troubling me. Here when I try to implement DFS, I see that my graph size is always 0. Can someone pls help me understand where to use the pointers.

#include<iostream>
#include<vector>
#include<map>
using namespace std;

void dfs_recursive(map<int, vector<int>> graph, bool visited[], int source){
    visited[source]=true;
    cout<<source<<" "<<endl;
    cout<<graph.size();
    for(int i=0;i<graph[source].size();i++){
        cout<<"i: "<<i<<endl;
        if(visited[graph[source][i]]==false)
            dfs_recursive(graph, visited, graph[source][i]);
    }
}

void addEdge(map<int, vector<int>> graph, int source, int dest){
    graph[source].push_back(dest);
    graph[dest].push_back(source);
}

int main(){
    int v=4;
    map<int, vector<int>> graph;
    bool visited[v]={false};
    addEdge(graph, 0, 1);
    addEdge(graph, 0, 4);
    addEdge(graph, 1, 2);
    addEdge(graph, 1, 3);
    addEdge(graph, 1, 4);
    addEdge(graph, 2, 3);
    addEdge(graph, 3, 4);

    dfs_recursive(graph, visited, 2);
}
Martin
  • 3,960
  • 7
  • 43
  • 43
  • That's not `c`. – Martin Aug 27 '21 at 14:16
  • 1
    There are no pointers in this code. – interjay Aug 27 '21 at 14:16
  • i know I havent used any pointers because im not sure where and how to use them – Shreya Birthare Aug 27 '21 at 14:17
  • 4
    C++ passes arguments by value, by default. When you call `addEdge(graph, 0, 1);`, the machine makes a copy of the `graph` argument to be used by `addEdge`. Then `addEdge` modifies this copy, which is discarded when it returns. If you want to have an effect on the `graph` object in main, you need to pass by reference. – Nate Eldredge Aug 27 '21 at 14:17
  • You don't need to use them. But you should use references if you want changes to parameters to be visible to the caller. – interjay Aug 27 '21 at 14:17
  • Remember, use pointers only when you HAVE to, in this code, seems like there is no need of pointers, without them you can just do fine. – Karen Baghdasaryan Aug 27 '21 at 14:26
  • 1
    In C you would need to use pointers for this, but C++ has references, which make it unnecessary. – Barmar Aug 27 '21 at 14:30
  • See https://stackoverflow.com/questions/13431108/changing-address-contained-by-pointer-using-function for how you would do it in C. – Barmar Aug 27 '21 at 14:30
  • also, why in dfs_recursive() we need not make the visited array a reference? – Shreya Birthare Aug 27 '21 at 14:32
  • As said above use references if you want to change data, const references if you are only going to use data passed to a function. For arrays consider std::array (compile time size know) or std::vector (size only know at runtime or a changing size) In c++ try to avoid pointers, work with references where you can. And IF you need pointers use std::unique_ptr (or possibly std::shared_ptr). No new/delete, but std::make_unique. It will avoid a lot of memory bugs. – Pepijn Kramer Aug 27 '21 at 14:38
  • "Help me understand where to use X to solve Y" is commonly called [The XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Consider focusing on the problem _Y_ "my graph size is always 0", rather than _X_ "where to use the pointers". – Drew Dormann Aug 27 '21 at 14:56

2 Answers2

1

Make the 1st argument in addEdge a reference, so it actually modifies the graph declared in your main() and not a copy of it.

void addEdge(map<int, vector<int>>& graph, int source, int dest){
    graph[source].push_back(dest);
    graph[dest].push_back(source);
}
m88
  • 1,968
  • 6
  • 14
  • also, why in dfs_recursive() we need not make the visited array a reference? – Shreya Birthare Aug 27 '21 at 14:31
  • Same thing for dfs_recursive() – m88 Aug 27 '21 at 14:47
  • what I want to know is that in case of "bool visited[]" array why dont we have to pass it as a reference? – Shreya Birthare Aug 27 '21 at 15:01
  • @ShreyaBirthare C-style arrays don't really have values other than a pointer to the first element in the array which you can safely pass by value. You don't need to modify the *location* of `visited`, nor could you. To the extent `visited` has a value, it's the address of its first element, which is constant anyway. – David Schwartz Aug 27 '21 at 15:25
0
void dfs_recursive(map<int, vector<int>> graph, bool visited[], int source){

As others have mentioned, to make this work you need to use references

void dfs_recursive(
    map<int, vector<int>>& graph,
    bool& visited[],
    int source){

Some other points:

  1. Not a good idea to use an array when you have std::vector available. Recommend visited should be a vector

  2. Not a good idea to have so many parameters for a recursive function. Each call puts them all on the stack. Prety soon you will run out of stack space. Reccomend you create a class, place parameters other than source as class attributes, and make the recursive function a method of the class.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103