0

I wrote a code to get the text file names in a directory, get the length of the articles which are number of words in article, and the two steps seem to work well, and the outputs are what I wanted. Here I used linked list to store all the file names, length and so on. But when I want to deal with the results stored in these structures. For example, get the number of text files whose lengths are within a range like 0-3, or get the maximum length of all the articles. There are no outputs of the corresponding codes. Would you please help me to figure out what the problem is? Here is my code, I wrote it in C++, IDE is Xcode:

///////////////////////////////////////////////////////
//part 1 works correctly, part 2 and 3 is not working//
///////////////////////////////////////////////////////

#include <iostream>
#include <string>

using namespace std;

struct WORDS{
int number_of_words;
string name;;
WORDS *next;
};
WORDS *head = new WORDS();
WORDS *current = new WORDS();

int main(){
string article[] = {"article1", "article2", "article3", "article4", "article5"};
head->name=article[0];
head->number_of_words = 0;
current = head;
for (int i = 1; i < 5; i ++) {
    current->next = new WORDS();
    current->next->name = article[i];
    current->next->number_of_words = i;
    current = current->next;
}

//part 1: print all the file names and their lengths
cout << "length of article (in words): \n";
current = head;
while (current->name != "\0") {;
    cout << current->name << "  " << current->number_of_words << '\n';
    current = current->next;
}

//part 2: find out the number of articles whose lengths are within range 0-3
current = head;
unsigned long count = 0;
while (current->name != "\0") {
    if (current->number_of_words > 0 && current->number_of_words <= 3){
        count ++;
        cout << "Articles with length from 0 to 3 are: " << '\n';
        cout << current->name << "  " << current->number_of_words << '\n';
    }
    current = current->next;
}
cout << "Number of articles within range is: " << count << '\n';

//part 3:find out the maximum length of all the articles
WORDS *max = new WORDS();
current = head;
max = head;

while (current->name != "\0") {
    if (current->next->number_of_words > max->number_of_words) {
        max = current->next;
    }
    current = current->next;
}

cout << "maximum length of all articles is: " << max->number_of_words << '\n';

return 0;
}

The output is just like this: (sorry I can't post images yet) length of article (in words):

article1 0

article2 1

article3 2

article4 3

article5 4

After "cout" in part 1, no more is printed.

OSrookie
  • 13
  • 3
  • Could you give us a minimal complete example? – Beta May 26 '13 at 02:24
  • you mean all the other functions? Or a result? – OSrookie May 26 '13 at 03:00
  • I have re-edited including the whole code – OSrookie May 26 '13 at 03:05
  • The idea of a [short, self-contained, correct example](http://sscce.org/) (what I call "minimal complete") is the simplest version of the code that produces the error. When you prepare it you often you find the bug in the process. If you don't prepare it, you force us to do a lot of extra work to even *attempt* to help you. The code now looks complete (is it C++11?). But what input will cause the error? And it's not minimal. It does two things, directory=>list and list=>results; you should see which goes wrong and post that one. And some code (e.g. `sort_umalphabetic`) is unused; remove it. – Beta May 26 '13 at 09:14
  • First of all, sorry for the inconvenience I've brought to you. This is actually my first formal question. I think I've come up with a version that is sort of a minimal complete example. In this example, I directly give filenames and lengths to "struct WORDS *". And they printed well, the problem lies in the second part looking for files whose lengths are from 0 to 3, and for the file with the maximum length. – OSrookie May 26 '13 at 11:40
  • I've edited again to make it simpler. By the way, I'm not sure whether it is C++11 or not. I'm using Xcode 4.5.1. I doubt that C++11 is in use by the release of this version. – OSrookie May 26 '13 at 11:58

1 Answers1

0

Starting here:

WORDS *current = new WORDS();

You use global variables when none are needed, but let that pass.

int main(){
  ...
  current = head;

You have just lost track of the memory you allocated with current = new WORDS() -- this is called a memory leak -- but let that pass.

current = head;
while (current->name != "\0") {;
  cout << current->name << "  " << current->number_of_words << '\n';
  current = current->next;
}

You never terminated the list with an element whose name was "\0". The last element in the list has an uninitialized next member which (almost certainly) doesn't point to a valid WORDS object. So when you set current to that value and dereference it (with current->name) you get undefined behavior.

There are several ways to prevent this. I suggest writing a constructor for WORDS which will set next to null by default, then test for that.

Beta
  • 96,650
  • 16
  • 149
  • 150
  • Thank you very much, it solves the problem even though I don't use a constructor. So can you give me a example of a constructor and how to use it? And for the memory leak problem, how can I keep track of the memory? Thank you again. – OSrookie May 26 '13 at 22:02
  • @OSrookie: You want me to teach you the whole C++ language? I'd be happy to, but my hourly rates are pretty high. – Beta May 27 '13 at 00:44