int numOfNodes= 0; // good practice: always initialize
int numOfEdges= 0; // ditto
FILE* file= fopen("input.txt", "r"); // ditto
// you should check fscanf return value
fscanf(file, "%d", &numOfNodes); //numOfNodes value is read in correct here
fscanf(file, "%d", &numOfEdges); //numOfEdges value is read in correct here
You should also check that those numbers are > 0.
This is bad, don't do this following:
ELEMENT **T = (ELEMENT**) new ELEMENT()
You're asking memory for just one element,
and the memory you're getting is ELEMENT*
.
By forcing the cast to ELEMENT**
, you are not only
doing something wrong, but telling the compiler 'trust me, I know what I'm doing'.
As a general rule in C++,
if you're casting, you're doing something bad.
There usually is a better way.
And don't use old style cast, prefer
reinterpret_cast, static_cast, dynamic_cast
and const_cast
.
If what you want is an array of ELEMENT*
,
then you should ask for it:
typedef ELEMENT* pElement;
ELEMENT** T= new pElement[numOfNodes]; // delete with delete[] T;
// or:
ELEMENT** T= malloc(sizeof(ELEMENT*) * numOfNodes); // delete with free(T);
Now you can do:
for (int i= 0; i < numOfNodes; i++) {
// This line is supposed to initialize all the Linked List inside the array to NULL.
// However on the second iteration the value for int numOfNodes changes to 0.
T[i]= NULL; // nullptr on C++11
}
In modern c++ I think the for is not needed if you do:
ELEMENT** T= new pElement[numOfNodes]{}; // delete with delete[] T;
Also you could use auto
:
auto T= new pElement[numOfNodes]{};
Note that you're not only removing explicit casts
but also implicit casts.
You could also have used in C++
std::vector, which grows as needed
std::vector<ELEMENT*> T(numOfNodes, NULL);
Passing (numOfNodes, NULL) as arguments
allocates numOfNodes elements initialized
with NULL.
Even while std::vector
lives on the stack
the memory for the elements lives on the heap.
You would access it the usual way:
T[10]= new ELEMENT();
Even better, in modern C++:
std::vector<unique_ptr<ELEMENT> > T(numOfNodes);
will construct a vector of smart pointers
that will call delete whenever you set them
to other value
T[10].reset(new ELEMENT(1)); // will set the pointer to a new element initialized with 1
T[10].reset(new ELEMENT(2)); // will set the pointer to a another new element
initialized with 2 and delete properly the old ELEMENT initialized with 1
T[10]->doSomething();
will work as usual.