-1

I am trying to write a simple function that fills an array of object pointers by detecting NULL indexes and creating new objects.

Wire *wireArray[MAX_WIRES];//The array is of class "Wire" and returns a pointer to a wire object. 

Wire *getWirePtrFromWireNum(int num); //the function gets the index to the array and returns a NULL if empty and the pointer if it is not NULL. 

In the following if-statement, I tried to pass the index to the function and create a new Wire object if the array at that number is NULL.

if (getWirePtrFromWireNum(wirenum) == NULL) {

                Wire newWire; 
                wireArray[wirenum] = &newWire; 

            }

The function for the getWirePtrFromWireNum simply checks for the NULL index and returns the pointer if it is occupied.

Wire * Circuit::getWirePtrFromWireNum(int num)
{
    if (wireArray[num] == NULL) {

        return NULL; 
    }

    else {

        return wireArray[num]; 

    }

}

When I test it with a several inputs, it does not enter first if-statement at all. I did not feel the need to initialize the pointer array to NULL, but I feel like it should still be catching that the first indexes should be empty. The code does not return any errors, but the function does not seem to be doing what it should be. Where could my error be coming from?

EDIT:

for (int i = 0; i < MAX_WIRE; i++) {

    wireArray[i] == NULL; 
}

Fixed Function:

Wire * Circuit::getWirePtrFromWireNum(int num)
{
    if (wireArray[num] == NULL) {

        wireArray[num] = new Wire; 
        return wireArray[num]; 

    }

    return wireArray[num]; 


}
Joe
  • 7
  • 5
  • [Any good reasons](https://stackoverflow.com/questions/46991224/are-there-any-valid-use-cases-to-use-new-and-delete-raw-pointers-or-c-style-arr) why to use raw pointers at all? – user0042 Dec 08 '17 at 02:51
  • Taking the address of a local variable that will go out of scope will only lead to sadness. – Retired Ninja Dec 08 '17 at 02:54

1 Answers1

0
if (wireArray[num] == NULL) {

    return NULL; 
}

else {

    return wireArray[num]; 

}

These statements don't do what you think that they do. You check wireArray == NULL, but it isn't set to NULL by default. In fact, the entire check is redundant because it can be simplified to return wireArray[num]. You need to initialize all of the elements in the array to NULL; their default values are whatever bits were left over from when the memory location was last used and are not defined.

if (getWirePtrFromWireNum(wirenum) == NULL) {

            Wire newWire; 
            wireArray[wirenum] = &newWire; 

}

You have a dangling pointer here. newWire is destroyed after the if statement.

Del
  • 1,309
  • 8
  • 21
  • How would I be able create an object for an if-statement condition is met without destroying the object? – Joe Dec 08 '17 at 03:58
  • @Joe I'm sorry, I don't quite understand what you're asking. If I'm understanding you correctly, no, you can't check if the element points to something valid because you simply *can't tell* if the memory location is valid or not by looking at it. You need to iterate over the array after its creation and set all the elements to `NULL`. – Del Dec 08 '17 at 04:01
  • Sorry if my question was confusing. I was wondering how I would be able to create a new object inside of an if-statement without it getting destroyed after the if-statement. If I wanted to create a new Wire after detecting a NULL index of the array, how would I do that without an if-statement? (Or without it getting destroyed after the if-statement). Thank you for your help. – Joe Dec 08 '17 at 04:05
  • You should read about the [heap and stack](https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap#80113). The stack is a portion of memory that is used for local variables, and after the portion of code that uses the stack frame is finished, all of the memory there is invalid. The heap is a portion of memory where data may be allocated and must be manually deallocated by the programmer. Heap memory is allocated with [new](http://en.cppreference.com/w/cpp/language/new) and freed with [delete](http://en.cppreference.com/w/cpp/language/delete). However, it's better – Del Dec 08 '17 at 04:10
  • practice to use [unique_ptr](http://en.cppreference.com/w/cpp/memory/unique_ptr), which automatically frees the heap data when it goes out of scope. – Del Dec 08 '17 at 04:11
  • Thanks again for the help. What would be a good way to create an object with a conditional statement then? I feel like I'd be limited without creating a local variable... – Joe Dec 08 '17 at 04:24
  • @Joe Well, like I said, if you want the object to outlive the conditional statement, you should allocate it on the heap with `new` or `std::unique_ptr`. However, I think that you should set all of the elements to a valid pointer when the array is first created instead of in a separate function. – Del Dec 08 '17 at 04:27
  • I applied what you said to my code. Would the editted code keep the variables in scope? Thanks again. – Joe Dec 08 '17 at 04:36
  • @Joe Yes, I think so. Just remember to use `delete` when the array goes out of scope, or else the values will stay in memory forever (this is called a memory leak). Is it possible for you to have an array of wires as opposed to an array of pointer to wires? That way, you don't have to worry about deleting the pointers. Also, you should check out [std::vector](http://en.cppreference.com/w/cpp/container/vector), which behaves like an array but is memory safe. I recommend for you use that instead. – Del Dec 08 '17 at 05:24
  • Thank you so much for all the help! I appreciate the patience and the willingness to contribute. – Joe Dec 08 '17 at 05:36