-1

I'm dealing with a Linked List. It's made up of classes. When I try to import information from a text file into the first pointer of the list with this function: (much more detailed description of my file hierarchy and code at the bottom)

void productList::readInProducts(){
    ifstream file;
    string line = "";

    cout << "What's the name of the file you would like to open?" << endl;
    getline(cin, input);//string input is in productList and shared between this function and writeOutProducts()
    file.open(input);

    if (!file.is_open())
    {
        cout << "Cannot open " << input << endl;
        return;
    }
    head->products.setName(line);
    getline(file, line);
    head->products.setPrice(stof(line));
    getline(file, line);
    head->products.setAmount(stoi(line));
    getline(file, line);
    while (!file.eof())
    {
        Node* n = new Node;
        n->products.setName(line);
        getline(file, line);
        n->products.setPrice(stof(line));
        getline(file, line);
        n->products.setAmount(stoi(line));
        getline(file, line);
        current = current->next;//make the current pointer point to the next node in the list
        current->next = n; //Set the current (empty) node equal to the n which contains three lines from the file
    }
}

I receive this error: Error Window

and visual studio opens up (what I assume is a CPP) file called xstring which has an break arrow pointing to line 2245 on it.

Now let me explain my code in a little more detail. I have five files: productList.h, productList.cpp, product.h, product.cpp, & main.cpp. Here's productList.h:

#include "product.h"
namespace std{
    class productList{
    public:
        productList();
        void addAProduct();
        void changeInventory();
        void printProducts();
        void readInProducts();
        void writeOutProducts();
    private:
        short count;
        string input; //Used to share the input between the read & write functions
        product products[200];
        struct Node{
            product products;
            Node* next;
        };
        Node* head;
        Node* current;
        Node* temp;
        Node* tail;
    };
}

And here's product.h:

#include <string>
namespace std{
    class product{
    public:
        product();
        string getName();
        void setName(string s);
        float getPrice();
        void setPrice(float p);
        int getAmount();
        void setAmount(int a);
    private:
        string name;
        float price;
        int amount;
    };
}

My productList.cpp file includes:

#include <iostream>
#include <fstream>
#include <iomanip>
#include "productList.h"

My product.cpp file just includes product.h and my main.cpp file (which contains my executing function) includes:

#include <iostream>
#include <array>
#include "productList.h"

Although these relations may seem a little convoluted, they should all be valid. The cpp files are linked to their header files with the exact same name (providing the header file exists), along with main.cpp being linked to productList.h and productList.h being linked to product.h. I can't see what I'm doing wrong with my code—although that's probably just because I'm having such a hard time understanding exactly how pointers work. I imagine that the error is in the code of my productList::readInProducts(){ function but I can't tell what's wrong.

Any help you guys can give would be greatly appreciated, as I am stumped. Here's a dropbox link to all the files: https://www.dropbox.com/s/9welj7k0yy2i1zj/productList.zip?dl=0

Logan Kling
  • 549
  • 2
  • 4
  • 16
  • It sounds like you have initialized a `std::string` with a nullpointer. Anyway, are you sure you want "head->products.setName(line); getline(file, line);" and not the opposite order of these statements, and other such pairs? – Cheers and hth. - Alf May 21 '15 at 23:56
  • If you're "having *such* a hard time understanding exactly how pointers work", you should try some simpler exercises. This code is hugely complicated, and you haven't given us enough to actually run it (i.e. it is [neither minimal nor complete](http://stackoverflow.com/help/mcve)). Play around with a linked list of `int`, and see how things go. – Beta May 21 '15 at 23:56
  • Once you've broken into the debugger after the exception, use the callstack window to get back to the place in your code that triggered the problem and point that out in your question. Based on the exception you've shown it looks like you're reading through a null pointer somewhere. – Retired Ninja May 22 '15 at 00:00
  • You should also read [this question](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) and change your code to actually check if your input is successful on every call. – Retired Ninja May 22 '15 at 00:04
  • 1
    @RetiredNinja Did you miss the `if (!file.is_open())` check? – Logan Kling May 22 '15 at 00:13
  • 1
    @Cheersandhth.-Alf I tried adding a `getline(file, line);` before `head->products.setName(line);`. I really thought that would work, or at least change something about my error, but I still got the exact same error. I've included a link to a zip file containing all the files (including the txt file) so that you can test this program out for yourself. – Logan Kling May 22 '15 at 00:23
  • @LarryK No, I did not. What if the 2nd of 3 getline calls fails because the file is malformed? Always check every call to input for success or failure. Links to external code go stale. You should reduce your code to a short complete example you can post in the question, not expect someone to dig around for it. – Retired Ninja May 22 '15 at 00:26
  • 1
    @RetiredNinja The file's not malformed, though. – Logan Kling May 22 '15 at 00:36
  • 1
    @Beta I added a dropbox link to the bottom of this post, which allows you to download a zip file containing all the files (including the text file) so that you can test this program out for yourself. – Logan Kling May 22 '15 at 00:52
  • 1
    The Internet is littered with computers corrupted because some programmer figured, "I don't have to test for that error condition." It is also littered because of people who figured, "Sure, I'll download that anonymous zip file." – user4581301 May 22 '15 at 00:55
  • I had some free time, so I tried downloading it; failed. It's zipped, not gzipped, and there's some kind of compatibility problem. [shrug] – Beta May 22 '15 at 01:19
  • 1
    productList.h shown above has more in it than productList.h in your DropBox zip file. Please update DropBox. While you're at it, please confirm that head is really initialized in the constructor when the crash occurs. – donjuedo May 22 '15 at 14:36
  • @donjuedo I updated the link and the code. – Logan Kling May 23 '15 at 18:48
  • @LarryK, class productList declares a struct Node type and 4 data members of type Node*. The DropBox source I just downloaded has none of that. – donjuedo May 24 '15 at 14:44

1 Answers1

1

You should initialize head, as well as the other Node*'s, in the productList constructor. Assuming you have already done that, a clear bug lies inside the while loop:

n = NULL;
n->products.setName(line);

That second line is dereferencing a null pointer, which can give 0xC0000005, an access violation. The 0x18 is probably the offset from null into the (non-existent) Node object's vtable, looking for positions.

To fix this, move the line:

Node* n = new Node;

inside the while loop, replacing the line:

n = NULL;

Please note: that also fixes another bug, the fact that the loop is meant to populate a new node with each pass, but the original code only calls new Node once.

donjuedo
  • 2,395
  • 14
  • 26
  • 1
    If I do that, the error message simply changes to: "Unhandled exception at 0x00195EFB in Linked List Inventory.exe: 0xC0000005: Access violation reading location 0x00000018." – Logan Kling May 22 '15 at 02:36
  • And once again, look at the callstack to find what line of your code is causing the issue. Knowing that will go a long way toward fixing the problem. – Retired Ninja May 22 '15 at 03:56
  • 1
    @RetiredNinja It's at the same line (2245). I have no idea what that means. – Logan Kling May 22 '15 at 04:47
  • 1
    The callstack window (alt+7 to show it although it is usually shown by default) gives you a list of functions that were called to get to where the debugger is now. You need to look at it and click the line where it shows a function you wrote, then you will know which part of your code is broken. – Retired Ninja May 22 '15 at 05:15