#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    5
    Rep Power
    0

    Segmentation Fault when attempting to use threads


    Hi!

    I am writing a program that searches for my name in a file downloaded from the internet. It begins by displaying a menu, then creating a thread for each option chosen. Here is my code so far:

    int searchforand(char* array, long filesize);
    int searchforscott(char **inarray, long filesize);
    int searchforjohnson(char **inarray, long filesize);

    int main(int argc, char** argv)
    {
    // initialize attributes
    pthread_attr_init(&attr);

    if (argc != 1)
    {
    cout << "Usage: " << argv[0] << endl;
    cout << "Searches for a word in a document. " << endl;
    cout << "No Arguments neccessary." << endl;
    exit(0);
    }

    int choice = 0;

    system("clear");

    cout << " Main Menu: \n";
    cout << "-------------------------------------------------------\n";
    cout << "1. Find string 'and' in data file 1\n";
    cout << "2. Find string 'scott' and 'johnson' in data file 2\n";
    cout << "3. Find string 'scott' and 'johnson' in data file 3\n";
    cout << "4. Exit\n\n";

    while (choice != 1 && choice != 2 && choice != 3 && choice != 4)
    {
    cout << "Please enter your choice: ";
    cin >> choice;

    // eliminate the exit possibility right off the bat
    if (choice == 4)
    {
    exit(0);
    }

    // if the choice is equal to 1
    if (choice == 1)
    {
    cout << "Thank you. Please wait...\n";

    // call function optionA()
    int ret = pthread_create(&thread1, &attr, optionA, NULL);
    // reset choice to zero to re-display menu
    choice = 0;


    }

    else if (choice == 2)
    {
    cout << "Thank you. Please wait...\n";

    pthread_create(&thread1, &attr, optionB, NULL);
    choice = 0;

    }

    else if (choice == 3)
    {
    cout << "Thank you. Please wait...\n";

    pthread_create(&thread1, &attr, optionC, NULL);
    choice = 0;
    }
    }


    return 0;
    }

    void* optionA(void* nullis) // function for first option
    {

    // get the file
    system("wget -q textfilefrominternet.txt1

    ifstream thefile("testcase1.txt");
    ofstream outputfile("testcase1a.txt");

    if (!thefile)
    {
    cout << "Error! File unable to be opened!\n";
    exit(0);
    }

    char temp;
    long filesize;
    if (!thefile || !outputfile) // if file can't be opened
    {
    cout << "Error! File unable to be opened!\n";
    exit(0);
    }

    // setting to lowercase, and creating a new file from which to read
    while (!thefile.eof())
    {
    thefile.get(temp);

    if (isupper(temp))
    {
    temp = tolower(temp); // convert to lowercase
    }

    filesize++;
    outputfile << temp;

    }

    thefile.close();
    outputfile.close();

    // create an array large enough to hold the entire file
    char *themassivearray = new char[filesize];
    long counter = 0;

    // place all of the characters into the new array
    ifstream newfile("testcase1a.txt");

    while (!newfile.eof()) // while not at the end of the file
    {
    newfile.get(temp);
    themassivearray[counter] = temp;
    counter++;
    }

    newfile.close(); // close it up when finished


    // search for the word 'and', using the newly created array
    int results = searchforand(themassivearray, filesize);

    // display results
    cout << "Results: Found " << results << " occurrances of the word \'and\'. \n";

    cout << "Freeing system resources...\n";

    delete themassivearray;
    system("unlink testcase1.txt");
    system("unlink testcase1a.txt");

    pthread_exit(NULL);

    }

    void* optionB(void* nullis)
    {
    system("wget -q textfilefrominternet2.txt
    ifstream thefile("testcase2.txt"); // the file used for input
    ofstream outputfile("testcase2a.txt"); // temp file, used briefly for output

    if (!thefile || !outputfile) // if file can't be opened
    {
    cout << "Error! File unable to be opened!\n";
    exit(0);
    }

    char temp;
    long filesize; // size of the file

    // setting to lowercase, and creating a new file from which to read
    while (!thefile.eof())
    {
    thefile.get(temp);

    if (isupper(temp))
    {
    temp = tolower(temp); // convert to lowercase
    }

    filesize++;
    outputfile << temp;

    }

    thefile.close();
    system("unlink testcase2.txt");

    outputfile.close();

    // create an array large enough to hold the entire file
    char *themassivearrayb = new char[filesize];
    long counter = 0;

    // place all of the characters into the new array
    ifstream newfile("testcase2a.txt");

    while (!newfile.eof()) // while not at the end of the file
    {
    newfile.get(temp);
    themassivearrayb[counter] = temp;
    counter++;
    }

    newfile.close(); // close it up when finished
    system("unlink testcase2a.txt");

    // search for the word 'and', using the newly created array
    int results = searchforscott(&themassivearrayb, filesize);

    // display results
    cout << "Results: Found " << results << " occurrances of the word \'scott\'. \n";

    results = searchforjohnson(&themassivearrayb, filesize);
    cout << "Results: Found " << results << " occurrances of the word \'johnson\'. \n";

    // free all allocated system resources
    cout << "Freeing system resources...\n";

    //delete themassivearrayb;
    // system("unlink testcase2.txt");
    // system("unlink testcase2a.txt");

    pthread_exit(NULL);

    }

    void* optionC(void* nullis) // same thing as option 2, just with a different file
    {
    system("wget -q textfilefrominternet.txt
    ifstream thefile("testcase3.txt");
    ofstream outputfile("testcase3a.txt");

    if (!thefile || !outputfile)
    {
    cout << "Error! File unable to be opened!\n";
    exit(0);
    }

    char temp;
    long filesize;

    // setting to lowercase, and creating a new file from which to read
    while (!thefile.eof())
    {
    thefile.get(temp);

    if (isupper(temp))
    {
    temp = tolower(temp);
    }

    filesize++;
    outputfile << temp;

    }

    thefile.close();
    outputfile.close();

    // create an array large enough to hold the entire file
    char *themassivearrayc = new char[filesize];
    long counter = 0;

    // place all of the characters into the new array
    ifstream newfile("testcase3a.txt");

    while (!newfile.eof())
    {
    newfile.get(temp);
    themassivearrayc[counter] = temp;
    counter++;
    }

    newfile.close();

    // search for the word 'and', using the newly created array
    int results = searchforscott(&themassivearrayc, filesize);

    // display results
    cout << "Results: Found " << results << " occurrances of the word \'scott\'. \n";

    results = searchforjohnson(&themassivearrayc, filesize);
    cout << "Results: Found " << results << " occurrances of the word \'johnson\'. \n";

    cout << "Freeing system resources...\n";

    delete themassivearrayc; // problems here, causes seg fault
    system("unlink testcase3.txt");
    system("unlink testcase3a.txt");

    pthread_exit(NULL);

    }


    int searchforand(char *inarray, long filesize)
    {
    int occurs = 0; // Return value

    // this function searches for wordtosearchfor in inarray
    // when finished, should return how many times it was found

    long cindex, nindex, lindex;
    int n;

    cindex = 0;

    while (cindex < filesize)
    {
    n = 1;

    while (n < 45)
    {
    nindex = cindex + n;
    lindex = nindex + n;

    if (inarray[cindex] == 'a' && inarray[nindex] == 'n' && inarray[lindex] == 'd')
    {
    occurs++;
    }

    else if (inarray[cindex] == 'd' && inarray[nindex] == 'n' && inarray[lindex] == 'a')
    {
    occurs++;
    }

    n++;
    }

    cindex++;
    }

    return occurs;
    }

    NOTE: Searchforscott() and searchforjohnson() use the same concept as searchforand()
    The problem is this -

    When I run the program, and immediately choose option 2, it causes a segmentation fault. I also have a problem sometimes if I run option 1, then option 2. Option 1 executes fine. Option 2, however, does not delete the file testcase2a.txt for some reason. I am totally confused. Is there anyone who might be able to give me a couple of hints?

    Thank you very much!

    ~Scott
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Please use code tags around your code listings to retain the indentation and keep them readable. Like HTML, only with square brackets and the keywords "code" and "/code" (not including the quotation marks).

    Just real quick: you didn't declare thread1, which should be of type pthread_t . You provided a pointer to thread1, which doesn't exist, so that pointer was invalid.

    But then it shouldn't have compiled, should it?
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    5
    Rep Power
    0
    Sorry about the /code code thing. I am new to the forum.

    ~Scott
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    5
    Rep Power
    0
    thread1 was declared earlier in the code, but I had to remove it in order to make the post shorter.

    ~scott
  8. #5
  9. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    5
    Rep Power
    0
    Here is the code again in a more readable format:
    Code:
     
    
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <ctype.h>
    #include <pthread.h>
    
    using std::cin;
    using std::cout;
    using std::endl;
    using std::string;
    using std::ifstream;
    using std::isupper;
    using std::tolower;
    using std::-ofstream;
    
    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_attr_t attr;
    
    
    void* optionA(void *arg);
    void* optionB(void *arg);
    void* optionC(void *arg);
    
    int searchforand(char* array, long filesize);
    int searchforscott(char **inarray, long filesize);
    int searchforjohnson(char **inarray, long filesize);
    
    int main(int argc, char** argv)
    {
    	// initialize attributes
    	pthread_attr_init(&attr);
    	
    	if (argc != 1)
    	{
    		cout << "Usage: " << argv[0] << endl;
    		cout << "Searches for a word in a document. " << endl;
    		cout << "No Arguments neccessary." << endl;
    		exit(0);	
    	}
    	
    	int choice  = 0;
    	
    	system("clear");
    
    	cout << "                     Main Menu:                        \n";
    	cout << "-------------------------------------------------------\n";
    	cout << "1. Find string 'and' in data file 1\n";
    	cout << "2. Find string 'scott' and 'johnson' in data file 2\n";
    	cout << "3. Find string 'scott' and 'johnson' in data file 3\n";
    	cout << "4. Exit\n\n";
    	
    	while (choice != 1 && choice != 2 && choice != 3 && choice != 4)
    	{
    		cout << "Please enter your choice: ";
    		cin >> choice;
    
    		// eliminate the exit possibility right off the bat
    		if (choice == 4)
    		{
    			exit(0);
    		}
    
    		// if the choice is equal to 1
    		if (choice == 1)
    		{
    			cout << "Thank you.  Please wait...\n";
    		
    			// call function optionA()
    			int ret = pthread_create(&thread1, &attr, optionA, NULL);	
    			// reset choice to zero to re-display menu
    			choice = 0;
    
    			
    		}
    
    		else if (choice == 2)
    		{
    			cout << "Thank you. Please wait...\n";
    
    			pthread_create(&thread1, &attr, optionB, NULL);
    			choice = 0;
    
    		}
    
    		else if (choice == 3)
    		  {
    		    cout << "Thank you.  Please wait...\n";
    		    
    		    pthread_create(&thread1, &attr, optionC, NULL);
    		    choice = 0;
    		  }
    	}
    
    	
    	return 0;
    }
    
    void* optionA(void* nullis) // function for first option
    {
    	
    	// get the file
    	system("wget -q internetfile.txt");
    
    	ifstream thefile("testcase1.txt");
    	ofstream outputfile("testcase1a.txt");
    
    	if (!thefile)
    	{
    		cout << "Error!  File unable to be opened!\n";
    	        exit(0);	
    	}
    	
    	char temp;
    	long filesize;
    	if (!thefile || !outputfile) // if file can't be opened
    	{
    		cout << "Error!  File unable to be opened!\n";
    	        exit(0);	
    	}
    	
    	// setting to lowercase, and creating a new file from which to read
    	while (!thefile.eof())
    	{
    		thefile.get(temp);
    		
    		if (isupper(temp))
    		{
    			temp = tolower(temp); // convert to lowercase
    		}
    		
    		filesize++;
    		outputfile << temp;
    		
    	}
    	
    	thefile.close();
    	outputfile.close();
    	
    	// create an array large enough to hold the entire file
    	char *themassivearray = new char[filesize];
    	long counter = 0;
    		
    	// place all of the characters into the new array
    	ifstream newfile("testcase1a.txt");
    
    	while (!newfile.eof()) // while not at the end of the file
    	{
    		newfile.get(temp);
    		themassivearray[counter] = temp;
    		counter++;
    	}
    
    	newfile.close(); // close it up when finished
    	
    		
    	// search for the word 'and', using the newly created array
    	int results = searchforand(themassivearray, filesize);
    
    	// display results
    	cout << "Results: Found " << results << " occurrances of the word \'and\'. \n";
    			
    	cout << "Freeing system resources...\n";
    	
    	delete  themassivearray;
    	system("unlink testcase1.txt");
    	system("unlink testcase1a.txt");
    	
    	pthread_exit(NULL);
    
    }
    
    void* optionB(void* nullis)
    {
    	system("wget -q internetfile2.txt");
    	ifstream thefile("testcase2.txt"); // the file used for input
    	ofstream outputfile("testcase2a.txt"); // temp file, used briefly for output
    
    	if (!thefile || !outputfile) // if file can't be opened
    	{
    		cout << "Error!  File unable to be opened!\n";
    	        exit(0);	
    	}
    	
    	char temp;
    	long filesize; // size of the file
    	
    	// setting to lowercase, and creating a new file from which to read
    	while (!thefile.eof())
    	{
    		thefile.get(temp);
    		
    		if (isupper(temp))
    		{
    			temp = tolower(temp); // convert to lowercase
    		}
    		
    		filesize++;
    		outputfile << temp;
    		
    	}
    	
    	thefile.close();
    	system("unlink testcase2.txt");
    
    	outputfile.close();
    	
    	// create an array large enough to hold the entire file
    	char *themassivearrayb = new char[filesize];
    	long counter = 0;
    		
    	// place all of the characters into the new array
    	ifstream newfile("testcase2a.txt");
    
    	while (!newfile.eof()) // while not at the end of the file
    	{
    		newfile.get(temp);
    		themassivearrayb[counter] = temp;
    		counter++;
    	}
    
    	newfile.close(); // close it up when finished
    	system("unlink testcase2a.txt");
    	
    	// search for the word 'and', using the newly created array
    	int results = searchforscott(&themassivearrayb, filesize);
    
    	// display results
    	cout << "Results: Found " << results << " occurrances of the word \'scott\'. \n";
    
    	results = searchforjohnson(&themassivearrayb, filesize);
    	cout << "Results: Found " << results << " occurrances of the word \'johnson\'. \n";
    			
    	// free all allocated system resources
    	cout << "Freeing system resources...\n";
    	
    	//delete themassivearrayb;
    	system("unlink testcase2.txt");
            system("unlink testcase2a.txt");
    	
    	pthread_exit(NULL);
    
    }
    
    void* optionC(void* nullis) // same thing as option 2, just with a different file
    {
    	system("wget -q internetfile3.txt");
    	ifstream thefile("testcase3.txt");
    	ofstream outputfile("testcase3a.txt");
    
    	if (!thefile || !outputfile)
    	{
    		cout << "Error!  File unable to be opened!\n";
    	        exit(0);	
    	}
    	
    	char temp;
    	long filesize;
    	
    	// setting to lowercase, and creating a new file from which to read
    	while (!thefile.eof())
    	{
    		thefile.get(temp);
    		
    		if (isupper(temp))
    		{
    			temp = tolower(temp);
    		}
    		
    		filesize++;
    		outputfile << temp;
    		
    	}
    	
    	thefile.close();
    	outputfile.close();
    	
    	// create an array large enough to hold the entire file
    	char *themassivearrayc = new char[filesize];
    	long counter = 0;
    		
    	// place all of the characters into the new array
    	ifstream newfile("testcase3a.txt");
    
    	while (!newfile.eof())
    	{
    		newfile.get(temp);
    		themassivearrayc[counter] = temp;
    		counter++;
    	}
    
    	newfile.close();
    	
    	// search for the word 'and', using the newly created array
    	int results = searchforscott(&themassivearrayc, filesize);
    
    	// display results
    	cout << "Results: Found " << results << " occurrances of the word \'scott\'. \n";
    
    	results = searchforjohnson(&themassivearrayc, filesize);
    	cout << "Results: Found " << results << " occurrances of the word \'johnson\'. \n";
    			
    	cout << "Freeing system resources...\n";
    	
    	delete themassivearrayc; // problems here, causes seg fault
    	system("unlink testcase3.txt");
    	system("unlink testcase3a.txt");
    	
    	pthread_exit(NULL);
    
    }
    
    
    int searchforand(char *inarray, long filesize)
    {
    	int occurs = 0;    // Return value
    	
    	// this function searches for wordtosearchfor in inarray
    	// when finished, should return how many times it was found
    
    	long cindex, nindex, lindex;
    	int n;
    
    	cindex = 0;
    	
    	while (cindex < filesize)
    	{
    		n = 1;
    
    		while (n < 45)
    		{
    			nindex = cindex + n;
    			lindex = nindex + n;
    
    			if (inarray[cindex] == 'a' && inarray[nindex] == 'n' && inarray[lindex] == 'd')
    			{
    				occurs++;
    			}
    
    			else if (inarray[cindex] == 'd' && inarray[nindex] == 'n' && inarray[lindex] == 'a')
    			{
    				occurs++;
    			}
    
    			n++;
    		}
    
    		cindex++;
    	}
    	
    	return occurs;	
    }
    ~Scott
  10. #6
  11. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    well where is the segfault occurring? what function and what line? set some breakpoints and see what is causing the problem. most likely you are deferencing an invalid pointer. one thing, in your option 2 if clause you havent checked the return value of pthread_create(), that would be a good place to start.
  12. #7
  13. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    5
    Rep Power
    0
    I have found that the segmentation fault is occurring due to the delete[] operator in OptionB(). If I comment out the delete, the program runs fine. Of course, doing so causes a memory leak, and I would like to deallocate memory, but I must be doing something wrong. I am also having trouble beacause when I run operations 1, 2, 3 in succession, optionC() won't get the file correctly, and exits.

    ~Scott
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    I don't see the delete[] statement in OptionB and in the unformatted listing in your first post it was commented out.

    Two things:
    1. I saw a simple delete of the char pointer in one function. An array new needs a delete[] .

    2. It is always good practice to initialize a pointer with the value of NULL; I always do this in the constructor. Then when you are ready to delete it, first test to see whether it is not NULL. If its value is still NULL, then nothing was ever allocated to it and the delete should not be performed. If it is not NULL, then something was allocated to it and delete is needed.
    Corollary: if the pointer will still be around for possible reuse after a delete, assign NULL to it again.

    A Question, since I had never encountered this problem: What happens when new encounters a problem and cannot perform the memory allocation? Like, in your case, if an invalid array size is passed to it (eg, if filesize is <= 0)? That might be worth looking into.
  16. #9
  17. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    A 'new' is supposed to throw an exception (the exception will say what the problem is), which if not caught, will cause the program to abort. A malloc (and bretheren) will return a NULL pointer, which, naturally, will cause a crash (on most OSs anyway) if dereferenced.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

IMN logo majestic logo threadwatch logo seochat tools logo