Thread: Hopefully novice code question.

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    3

    Hopefully novice code question.

    Hello everyone! This will be my first time posting, but not my first time acquiring knowledge from this veritable cornucopia. I do hope that I am properly following all of the guidelines, and that my question isn't too vague.

    Essentially I had a homework assignment where I needed to do a number of things to an array of objects. They were of two classes, student()erson(), and faculty();person() that were both under an array called pPoint[50], where the students had 0-24, and the faculty had 25-49. I was able to get the program working on all fronts, aside from a sorting function.

    I slaved away at the function, thinking that I had everything syntactically correct. Every time that I access this part of the program however, my debugger goes bananas (Visual Studio 2010). Every time I get to this section, it gives me the following, "Unhandled exception at 0x00e63b66 in Homework4.exe: 0xC0000005: Access violation reading location 0xcccccd04."

    Is there something incorrect that I have done here? Side note, if more code is needed, please let me know. I just didn't want to flood the page with the program.

    Thank you to all who read this posting.
    -Me

    Code:
    for (sortA = 0; sortA < 23; sortA++)
    				{
    					for (sortB = 0; sortB < 23; sortB++)
    					{
    						if (pPoint[sortB]->getName() > pPoint[sortB+1]->getName())
    						{
    							sortC = pPoint[sortB+1]->getName();
    							pPoint[sortB+1]->setName(pPoint[sortB]->getName());
    							pPoint[sortB]->setName(sortC);
    						}
    					}
    				}

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Please post your class definition for your pPoint variable, and show how your declared pPoint.

    Jim

  3. #3
    Programming King Mr.777's Avatar
    Join Date
    Mar 2011
    Location
    Middle of NoWhere
    Posts
    320
    If 23 is the maximum size of your array pPoint, it should definitley crash while execution but as jimblumberg said, post your code here so that we could have a look over the variables declarations and initiliazations...
    Regards...
    I don't care if someone doesn't like me, i was not put on earth to entertain everyone.

    No King, no Queen, I am the ACE of battle.

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    3

    Roger.

    Here is the lot of it.

    Some of the code is a little asinine, but it was for a class project, so the instructor just needed to see that we knew our syntax, etc. The program has been turned in, I was mostly just bothered by that one part not working properly.

    Code:
    //Use one array of type Person
    
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Person
    {
    private:
    	string id;
    	string name;
    	string address;
    	
    
    public:
    	void setId(string i) {id = i;}
    	void setName(string n) {name = n;}
    	void setAdd(string a) {address = a;}
    
    	string getId() {return id;}
    	string getName() {return name;}
    	string getAdd() {return address;}
    
    	Person() {setName(" "); setId(" "); setAdd(" ");}
    	Person(string i, string n, string a){setName(n); setId(i); setAdd(a);}
    	
    	virtual void print() {cout << endl << "Name: " << name << " ID: " << id << " Address: " << address << endl;}
    };
    
    class Student : public Person
    {
    private:
    	double gpa;
    	string status;
    
    public:
    	void setGpa(double g) {gpa = g;}
    	void setStatus(string s) {status = s;}
    
    	double getGpa() {return gpa;}
    	string getStatus() {return status;}
    
    	Student():Person()
    	{
    		gpa = 0.0;
    		status = " ";
    	}
    
    	Student (double g, string s, string i, string n, string a):Person(i, n, a)
    	{
    		gpa = g;
    		status = s;
    	}
    	
    	void print() {cout << endl << "Name: " << Person::getName() << " ID: " << Person::getId() << " Address: " 
    		               << Person::getAdd() << " GPA: " << gpa << " Graduate Status: " << status << endl;}
    };
    
    class Faculty : public Person
    {
    private:
    	string department;
    	string rank;
    
    public:
    	void setDepartment(string d) {department = d;}
    	void setRank(string r) {rank = r;}
    
    	string getDepartment() {return department;}
    	string getRank() {return rank;}
    
    	Faculty():Person()
    	{
    		department = " ";
    		rank = " ";
    	}
    
    	Faculty (string d, string r, string i, string n, string a):Person(i,n,a)
    	{
    		department = d;
    		rank = r;
    	}
    	
    	void print() {cout << endl << "Name: " << Person::getName() << " ID: " << Person::getId() << " Address: " 
    					   << Person::getAdd() << " Department: " << department << " Rank: " << rank << endl;}
    };
    
    int menuThing(int z);
    
    int main()
    {
    	int exitParam = 0;
    	int choice;
    	int sCounter = 0;
    	int fCounter = 25;
    
    	int sortA = 0;
    	int sortB = 0;
    	
    	string tempid = " ";
    	string tempname = " ";
    	string tempadd = " ";
    	string sortC = " ";
    
    	Person *pPoint[50];
    	
    	
    
    	while (exitParam == 0)
    	{
    		cout << endl << "1-For Student" << endl << "2-For Faculty" << endl << "3-Exit" << endl << ">>> ";
    		cin >> choice;
    
    		if (choice == 1)
    			switch (menuThing(1))
    		{
    			case 1:
    				system("cls"); 
    
    				if (sCounter > 24)
    				{
    					cout << endl << "No more room for Students!" << endl;
    					break;
    				}
    
    				cout << "\t\tAdd a student." << endl;
    				pPoint[sCounter] = new Student();
    
    				cout << "Enter id: ";
    				//cin >> tempid;
    				fflush(stdin);
    				getline(cin, tempid);
    				pPoint[sCounter]->setId(tempid);
    				cout << endl << "Enter full name : ";
    				fflush(stdin);
    				getline(cin, tempname);
    				pPoint[sCounter]->setName(tempname);
    				cout << endl << "Enter Address: ";
    				fflush(stdin);
    				getline(cin, tempadd);
    				pPoint[sCounter]->setAdd(tempadd);
    				cout << endl << endl << "Student added!" << endl;
    				
    				if (sCounter < 25)
    					sCounter++;
    				if (sCounter > 24)
    					cout << endl << "No more room for Students!" << endl;
    				break;
    			case 2:
    				break;
    			case 3:
    				break;
    			case 4:
    				for (sortA = 0; sortA < 23; sortA++)
    				{
    					for (sortB = 0; sortB < 23; sortB++)
    					{
    						if (pPoint[sortB]->getName() > pPoint[sortB+1]->getName())
    						{
    							sortC = pPoint[sortB+1]->getName();
    							pPoint[sortB+1]->setName(pPoint[sortB]->getName());
    							pPoint[sortB]->setName(sortC);
    						}
    					}
    				}
    				break;
    			case 5:
    				break;
    			default:
    				cout << endl << "Invalid selection." << endl;
    				break;
    		}
    		if (choice == 2)
    			switch (menuThing(2))
    		{
    			case 1:
    				break;
    			case 2:
    				break;
    			case 3:
    				break;
    			case 4:
    				break;
    			case 5:
    				break;
    			default:
    				cout << endl << "Invalid selection." << endl;
    				break;
    		}
    		if (choice == 3)
    			exitParam = 1;
    	}
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	system("pause");
    	return 0;
    }
    
    
    
    int menuThing(int z)
    {
    	int selection = 0;
    	if (z == 1)
    	{
    		system("cls");
    		cout << endl << "1) Add a new student" << endl;
    		cout << "2) Print the information for a student" << endl;
    		cout << "3) Delete a student" << endl;
    		cout << "4) Sort students by name" << endl;
    		cout << "5) Quit" << endl;
    		cout << "Enter your selection : ";
    		cin >> selection;
    	}
    
    	if (z == 2)
    	{
    		system("cls");
    		cout << endl << "1) Add a new faculty" << endl;
    		cout << "2) Print the information for a faculty" << endl;
    		cout << "3) Delete a faculty" << endl;
    		cout << "4) Sort faculty by name" << endl;
    		cout << "5) Quit" << endl;
    		cout << "Enter your selection : ";
    		cin >> selection;
    	}
    
    	return selection;
    }

  5. #5
    Programming King Mr.777's Avatar
    Join Date
    Mar 2011
    Location
    Middle of NoWhere
    Posts
    320
    I first enter 1 and then 4.
    Now check your pointer condition....
    Your pointer is not pointing to any where, means it's a dangling pointer.
    Now, start handling it...
    Good luck
    I don't care if someone doesn't like me, i was not put on earth to entertain everyone.

    No King, no Queen, I am the ACE of battle.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    A couple of things. First off, is it really necessary to use new here? If it is, then you are not freeing everything. Either use delete or use a smart pointer (see SourceForge.net: Raw pointer issues - cpwiki).
    Secondly, fflush(stdin) is undefined. Don't use it. Ever. SourceForge.net: Fflush - cpwiki. Also, do not mix C and C++-style I/O. The result is, again, undefined. fflush is C. getline is C++.
    Also consider that your sort function will sort all objects. But what happens if you have less than 50 objects? You will have pointers pointing to neverland!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    3
    As far as necessary, it was what our instructor wanted us to do. He's had us do a ton of things that were essentially nonsense, just to try to demonstrate that we understand syntax.

    I tried it using sCounter-1 in the sorting for loops, and it didn't give me the error.

    I think I understand what you are saying in that it is trying to access a piece of data that doesn't exist.

    In regards to not using fflush, what alternative is there?

    Also, I have done some searches, and there is so much information, and so many books out there, it's hard for someone like myself to know where even to start. Being a novice, when I pull up some of the pages that I am referenced to, they are full of information that I just don't understand yet. It can occasionally be frustrating, but it's still a tremendously fun hobby.
    Last edited by jcapstone; 03-25-2011 at 11:02 AM. Reason: additional question/information

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Best way:

    #include <limits>
    std::cin.ignore(std::numerical_limits<int>::max()) ;

    Or if you can't memorize that, just

    std::cin.ignore(n);

    Where n is a sufficiently large n to clear out anything left in the input buffer, say, 1000 or so.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    see SourceForge.net: Raw pointer issues - cpwiki
    Take this with a grain of salt: it's more like Elysia's personal take on the subject. This article isn't even linked anywhere else in the rest of the encyclopedia. And no one besides him edits the pages anymore.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Oh indeed? To me, it clearly points out some issues with raw pointers and solutions to those problems.
    Or rather I should say, instead of criticizing the article, help out by fixing it or pointing out its flaws instead of steering people away from resources.
    Last edited by Elysia; 03-25-2011 at 11:43 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    it clearly points out some issues with raw pointers and solutions to those problems.
    Even if I agreed, it's still largely your opinion on the subject. Take this:
    What happens, if somewhere inside the function, something throws an exception? Considering that we've allocated some memory with new, we must delete that, but if an exception is thrown, then the execution of the code will follow on the nearest catch block. So that means, that to ensure we do not leak memory, we have to make a local catch block, try to free all the memory allocated, then re-throw the exception.
    This happens since raw pointers are not automatically freed, and thus can be quite cumbersome.

    An example of how to do this is not offered, since it is not considered a good solution.
    However, a curious reader may wonder. Clearly, we can associate this problem with many other things, such as writing some information to a file, or some like. Some operation that, if the function fails, must be rolled back. That is, undone. Surely smart pointers cannot be used for all these things? Well, yes and no. While smart pointers are indeed powerful, they cannot do everything. Discussion of exception safety is a topic of its own and is not the scope of this article. Instead, a curious reader is directed to reading about Boost.ScopeExit.
    How is that not entirely your opinion on what a good solution is? I mean, you mention that you can catch an exception in the constructor and then rethrow the exception after deleting, but it's not considered a good solution and is quite cumbersome. No one necessarily knows why, and even if we did that's your opinion.

    Recommending smart pointers is OK, but I don't see them using a different technique to make their code exception safe. Much better articles are abound, such as this one: pointers.

    The other part of it is literally just about how delete is easy to forget and how smart pointers are just better, which I don't find to be educational.

    The ticking time bomb solution code still has syntax errors. return; instead of return *this;

    Since no one edits the pages anymore, I'd rather see that site become obscure. But I think largely what you have to say here needs to be integrated into the pointers page.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by whiteflags View Post
    How is that not entirely your opinion on what a good solution is? I mean, you mention that you can catch an exception in the constructor and then rethrow the exception after deleting, but it's not considered a good solution and is quite cumbersome. No one necessarily knows why, and even if we did that's your opinion.
    No, I think that is quite widely accepted, and shared among many as a good solution, because catching and rethrowing exceptions is just not something I see recommended. The recommended solution is use RAII, and that is exactly what smart pointers do.

    Recommending smart pointers is OK, but I don't see them using a different technique to make their code exception safe. Much better articles are abound, such as this one: pointers.
    Changing their code to make it exception safe? Probably not. But it is valuable knowledge for future projects. Exceptions are a big part of C++, and smart pointers play a huge role in making exception safe code, and that is mostly what the article wants to bring forth.
    Is the wording wrong? Perhaps. These things are all too subjective.

    The other part of it is literally just about how delete is easy to forget and how smart pointers are just better, which I don't find to be educational.
    For newbies, I find it very educational since a lot of newbies don't even call delete in the first place.

    Since no one edits the pages anymore, I'd rather see that site become obscure. But I think largely what you have to say here needs to be integrated into the pointers page.
    So where do you put up FAQs and articles on subjects, then? The board? The FAQ board which isn't used? The FAQ page on the site which pretty much isn't used?
    The point is, the site is a place to store such articles so that we don't have to repeat things. And frankly, lengthy explanations do not tend to be incorporated into replies. That means newbies get less useful information rather than if there was a site where articles were written full of good information.

    But even for all this debate, I still fail to see why it would be bad to refer people to that article. It may not be perfect. It is not meant to be perfect. It is meant to be usable.
    Last edited by Elysia; 03-25-2011 at 12:27 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Elysia View Post
    Oh indeed? To me, it clearly points out some issues with raw pointers and solutions to those problems.
    Or rather I should say, instead of criticizing the article, help out by fixing it or pointing out its flaws instead of steering people away from resources.
    I am inclined to agree with elysia on this one. raw pointers are almost completely obsolete in C++. there are very few cases where you MUST use a raw pointer. nearly everything can (and should) be done with the appropriate facility in the C++ standard library - string, vector, auto_ptr/shared_ptr, etc. in todays environment of malware, safety and security are EVERYTHING. pointers provide absolutely no safety. in my own code, I try to use references whenever it is possible, using pointers only when I need to dynamically create something that needs to persist outside the scope in which it was created.

  14. #14
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Elysia View Post
    No, I think that is quite widely accepted, and shared among many as a good solution, because catching and rethrowing exceptions is just not something I see recommended. The recommended solution is use RAII, and that is exactly what smart pointers do.
    If the recommended solution is to use RAII, and catching exceptions from a constructor, cleaning up after the constructor, and rethrowing the exception follows RAII, then why is it not recommended? Is that not entirely your opinion?
    Changing their code to make it exception safe? Probably not. But it is valuable knowledge for future projects. Exceptions are a big part of C++, and smart pointers play a huge role in making exception safe code, and that is mostly what the article wants to bring forth.
    Is the wording wrong? Perhaps. These things are all too subjective.
    I meant that shared pointer implementations also throw exceptions from constructors and call delete p before reraising it. So, since it is a used solution and you're going to mention it, I don't see how it's correct to say it's not recommended. Even if it's not recommended, it's in your opinion only.


    So where do you put up FAQs and articles on subjects, then? The board? The FAQ board which isn't used? The FAQ page on the site which pretty much isn't used?
    Who said it wasn't used? People link to it all the time on here.

    But even for all this debate, I still fail to see why it would be bad to refer people to that article. If may not be perfect. It is not meant to be perfect. It is meant to be usable.
    I don't think an article that's largely someone's unsupported dubious opinions is useable, or I wouldn't have brought it up.
    Last edited by whiteflags; 03-25-2011 at 12:36 PM.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by whiteflags
    I don't think an article that's largely someone's unsupported dubious opinions is useable, or I wouldn't have brought it up.
    Well, it might be usable, but not present a complete picture. That said, I don't think the code for "write a custom copy constructor and assignment operator that makes a copy of the raw pointer and does not merely copy over the raw pointer's value" is usable: it is not exception safe and does unnecessary work.

    It is not exception safe because delete m_int in the copy assignment operator is used before m_int = new int. Since new int could throw std::bad_alloc, it should be done first, i.e., using another variable that is then assigned to m_int after the delete. But I say that this is unnecessary work because there was no need to use delete in the first place (but then there was no need to use a pointer in the first place, so perhaps this is not a valid objection).

    Furthermore, unlike the copy and swap idiom, the use of the copy assignment operator to implement the copy constructor is not a normal idiom, in my opinion. Given that the use of a pointer is contrived to demonstrate new and delete, I might have written:
    Code:
    A(const A& rhs) : m_int(new int(*rhs.m_int)) {}
    
    A& operator = (const A& rhs)
    {
        if (&rhs != this)
        {
            int* temp = new int(*rhs.m_int);
            delete m_int;
            m_int = temp;
        }
        return *this;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A rather broad code design question
    By Walker in forum C++ Programming
    Replies: 6
    Last Post: 01-27-2010, 07:09 PM
  2. Novice Pointers/Class Question
    By C++Gamer in forum C++ Programming
    Replies: 8
    Last Post: 06-28-2006, 05:36 PM
  3. I need help to compile this code...
    By wise_ron in forum C Programming
    Replies: 17
    Last Post: 05-07-2006, 12:22 PM
  4. Newbie Question - fflush(stdin) & fpurge(stdin) on Mac and PC
    By tvsinesperanto in forum C Programming
    Replies: 34
    Last Post: 03-11-2006, 12:13 PM
  5. End of Code Loop Question
    By JuanSverige in forum C++ Programming
    Replies: 1
    Last Post: 04-08-2003, 10:35 AM