C/C++ Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
 



Go Back   Dev Articles Community ForumsProgrammingC/C++ Help

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Dev Articles Community Forums Sponsor:
  #1  
Old September 21st, 2008, 02:01 AM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Memory Deallocation and Friend (EDIT)

Hi, recently started doing a custom String class (school :/). Finally got pointers and references out of the way and now I am well under way into testing. Started out by testing the concat function, and I run into a Segmentation Fault.
Normally, they are easy to figure out where it is, and from there it's just a matter of time before solving it. However, this time... I've found where it is, but it is at the strangest of places and I can't understand why it would seg fault there. This program does not allow the vector class or any cctype and string related funcs. Thus I am forced to do dynamic array with pointers.

So first off there's an AltString.h class, then an AltString.cc and a tester file.

This is what the tester file looks like so far:

Code:
        AltString newString;
        newString.display();
        AltString newString2('a');
        newString2.display();
        AltString newString3('a');
        newString3.display();
        newString2 = newString2.concat(newString3);
        cout << "Hello 1" << endl;
        newString2.display();
        return 0;


Now... the whole thing runs fine until newString2 = newString2.concat(newString3);

At first I thought it would be the concat function, so I threw in a cout statement on the FIRST line in the concat funcs. It never print. So it's faulting on the line concat is invoked, but it never actually prints the first line in concat. It seems like newString2 or newString3 is wrong, but they printed fine, meaning the Constructors are actually working.
What can be the problem? Any help would be appreciated

Reply With Quote
  #2  
Old September 21st, 2008, 08:55 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Could you post the concat function, or even better, the whole AltString class?
__________________
There is no such thing as C/C++, you either program C or C++

Reply With Quote
  #3  
Old September 21st, 2008, 10:24 AM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Here is the AltString.cc

The 2 private data member of the AltString class is:
char * arrayPointer;
int arraySize;
which both are in AltString.h

Code:
#include <iostream>
#include "AltString.h"
using namespace std;

AltString::AltString()
{
        arrayPointer = new char[1];
        setArraySize(1);
}

AltString::AltString(char ch)
{
        arrayPointer = new char[1];
        setAt(0, ch);
        setArraySize(1);
}

AltString::AltString(int size)
{
        arrayPointer = new char[size];
        setArraySize(size);
}

AltString::AltString(const AltString& otherAltString)
{
        setArraySize(otherAltString.length());
        for(int i = 0; i < arraySize; i++)
        {
                setAt(i, otherAltString.charAt(i));
        }
}

AltString::AltString(const char*& nullTermString)
{
        int index = 0;
        while(true)
        {
                int i = 0;
                if(nullTermString[i] == '\0')
                {
                        index = i;
                }
                i++;
        }
        for(int j = 0; j < index; j++)
        {
                setAt(j, nullTermString[j]);
        }
        setArraySize(index);
}

AltString::~AltString()
{
        delete [] arrayPointer;
        setArraySize(0);
}

int AltString::compare(const AltString& stringA, const AltString& stringB)
{
        bool isEqual = false;
        int shorterLength = 0;
        if(stringA.length() > stringB.length())
        {
                shorterLength = stringA.length();
        }
        else if(stringA.length() < stringB.length())
        {
                shorterLength = stringB.length();
        }
        else
        {
                shorterLength = stringA.length();
                isEqual = true;
        }
        for(int i = 0; i < shorterLength; i++)
        {
                int x = stringA.charAt(i);
                int y = stringB.charAt(i);
                if(x < y)
                {
                        return -1;
                }
                else if(x > y)
                {
                        return 1;
                }
        }
        if(isEqual)
        {
                return 0;
        }
        if(stringA.length() < stringB.length())
        {
                return -1;
        }
        else
        {
                return 1;
        }
}

char AltString::charAt(int index) const
{
        char newChar = ' ';
        if(index < 0)
        {
                index = 0;
        }
        else if(index >= length())
        {
                index = length() - 1;
        }
        newChar = arrayPointer[index];
        return newChar;
}

AltString& AltString::concat(AltString otherAltString)
{
        cout << "CONCAT HELLO" << endl;
        int newLength = length() + otherAltString.length();
        AltString* newString = new AltString(newLength);
        newString->setArraySize(newLength);
        for(int i = 0; i < length(); i++)
        {
                newString->setAt(i, charAt(i));
        }
        for(int i = 0; i < otherAltString.length(); i++)
        {
                newString->setAt(i + length(), otherAltString.charAt(i));
        }
        return *newString;
}

void AltString::display() const
{
        for(int i = 0; i < length(); i++)
        {
                cout << charAt(i);
        }
        cout << endl;
}

int AltString::indexOf(char ch) const
{
        for(int i = 0; i < length(); i++)
        {
                if(charAt(i) == ch)
                {
                        return i;
                }
        }
        return -1;
}

int AltString::length() const
{
        return arraySize;
}

bool AltString::setAt(int index, char ch)
{
        if(index > length() || index < 0)
        {
                return false;
        }
        else
        {
                arrayPointer[index] = ch;
                return true;
        }
}

AltString& AltString::subString(int low, int high) const
{
        AltString* newString = new AltString;
        if(high > low)
        {
                if(high > length() - 1)
                {
                        high = length() - 1;
                }
                if(low < 0)
                {
                        low = 0;
                }
                newString->setArraySize(high - low);
                for(int i = 0; i < newString->length(); i++)
                {
                        newString->setAt(i, charAt(i));
                }
        }
        for(int i = 0; i < newString->length(); i++)
        {
                newString->setAt(i, charAt(i));
        }
        return *newString;
}

AltString& AltString::toUpper()
{
        for(int i = 0; i < length(); i++)
        {
                int x = charAt(i);
                if(x > 97 && x <= 122)
                {
                        x = x - 32;
                        char newChar = static_cast<char>(x);
                        setAt(i, newChar);
                }
        }
        return *this;
}

AltString& AltString::toLower()
{
        for(int i = 0; i < length(); i++)
        {
                int x = charAt(i);
                if(x > 65 && x <= 90)
                {
                        x = x + 32;
                        char newChar = static_cast<char>(x);
                        setAt(i, newChar);
                }
        }
        return *this;
}

AltString& AltString::reverse()
{
        AltString* newString = new AltString;
        newString->setArraySize(length());
        for(int i = 0; i < length(); i++)
        {
                newString->setAt(i, charAt(length() - i));
        }
        return *newString;
}

//stringArray functions

void AltString::setArraySize(int newSize)
{
        arraySize = newSize;
}

Reply With Quote
  #4  
Old September 21st, 2008, 11:15 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Your copy constructor does not allocate any memory for the buffer (arrayPointer). The class has no assignment operator so the compiler will generate one for you, but that one will also probably not do the correct thing. The concat function takes the AltString parameter by value so a temporary copy will be made which is passed to the concat function.

The temporary copy is initialised using the copy constructor, since the arrayPointer pointer is uninitialised you are writing to a random memory location there. So do a 'new' for your arrayPointer in the copy constructor. Also, create an assignment operator which resizes the buffer before copying the other string to it.

I hope this is clear Let me know your results

Reply With Quote
  #5  
Old September 21st, 2008, 11:19 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
You could of course also pass the AltString parameter to concat() by (const) reference. Note that you probably have a memory leak in your concat method. You are creating a new AltString on the heap there and returning it by reference. Deleting a reference (i.e., delete &referenceVar; ) is not very good form imho.

These school exercises really make you appreciate the standard classes Outside of school you should probably never make your own string class.

Reply With Quote
  #6  
Old September 21st, 2008, 11:53 AM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Woot, with the initialization of the arrayPointer inside the copy function, the concat worked! Thanks!

I don't exactly understand what you mean by deleting. I know I have to take care of memory leaks, but I haven't even started on that because the whole thing is still somewhat unclear to me right now.
I was thinking that in functions such as reverse that requires me to make a new AltString and point the current pointer to it means I have to delete whatever the pointer is pointing to, then redirect the pointer to point the new AltString as the current one. But I am not too sure how to do this, since the pointer is for an array. Do I go through an entire for loop and repoint every element into another AltString's elements? I know deleting an arrayPointer is delete [] arrayPointer, but I am not sure on other syntax.
I'd wish I can change some parameters around, but those are set for the project

Also, for the destructor and such. Do I have to manually call it in the tester file to delete an AltString I no longer want (if not, where do I use it?)? And I supposed I have to handle both memory and pointer leaks in each individual functions, or am I offtrack?

Reply With Quote
  #7  
Old September 21st, 2008, 12:07 PM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Well, I am not sure what your project is exactly about and what the restrictions are but, with reverse() for instance:
cpp Code:
Original - cpp Code
  1. AltString& AltString::reverse()
  2. {
  3.         AltString* newString = new AltString; // <-- creating a new AltString in freestore (heap) here
  4.         newString->setArraySize(length());
  5.         for(int i = 0; i < length(); i++)
  6.         {
  7.                 newString->setAt(i, charAt(length() - i));
  8.         }
  9.         return *newString;
  10. }
now if you would use this function like this:
cpp Code:
Original - cpp Code
  1. AltString newString('a');
  2. AltString string2 = newString.reverse();
you have a memory leak because the 'newed' AltString is never deleted (as well as the internal pointer of course).
If you would call it like this:
cpp Code:
Original - cpp Code
  1. AltString newString('a');
  2. AltString& string2 = newString.reverse();
  3. delete &string2; // You could delete like this
  4.  
but this is quite 'unelegant'.

I am not sure what your assignment is, maybe this is irrelevant for you at this moment. But it is good to be aware of.

Reply With Quote
  #8  
Old September 21st, 2008, 12:17 PM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
What would be the elegant way to delete it? My professor grades on project design as well, which is good since it forces people to get into good habits and format.

And for reference, this is the project page:

LINK

It's mostly just we can't use cctype, string, vector class related functions, and that we should take care of memory leaks. Other than that it's correctness of the program and design.

Reply With Quote
  #9  
Old September 21st, 2008, 12:27 PM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Depends. You mentioned the parameters for the functions are set, right? As well as the return values I guess? In that case I am wondering what your professor is thinking, i.e., what he/she wants you to do.

I am suspecting that the intention of reverse() and concat() is actually that you modify the string itself (i.e. the object they are called on) instead of creating a new string and returning that. I also suspect the return value, which is an AltString reference, is not supposed to be a new string but a reference to the current string itself. This might seem redundant but it enables you to 'chain' function calls, like this:
cpp Code:
Original - cpp Code
  1. AltString s1('a');
  2. AltString s2 = s1.reverse().reverse(); // silly example, but you can see what I mean by chaining
  3.  


If you would modify the string 'in-place' then you do not need to 'new' a new AltString and thus you do not need to delete anything (except maybe when modifying the internal buffer).

If it is not clear I can conjure up an example if you want. (Although I am about to step away from my computer for the rest of the day, so it might take until tomorrow)

Reply With Quote
  #10  
Old September 21st, 2008, 12:37 PM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
I am sure he wants us to make a new AltString inside those functions. He wanted us to get used to pointers, classes, memory allocation/deallocation among others.

Reply With Quote
  #11  
Old September 21st, 2008, 12:53 PM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Ok, so he (are there even any female CS professors? ) wants you to at least do the pointer stuff inside the class, but I guess he wants you to use 'value semantics' (as opposed to reference semantics, i.a.w., pointers) in the interface of the class.

You could implement reverse() like this:
cpp Code:
Original - cpp Code
  1. AltString& AltString::reverse()
  2. {
  3.         // make a temporary buffer with the same size as current string buffer
  4.         char* temp = new char[length()];
  5.      
  6.         // copy the current contents to the temporary buffer in reverse
  7.         for(int i = 0; i < length(); i++)
  8.         {
  9.                 temp[i] = arrayPointer[length() - i];
  10.         }
  11.  
  12.         // delete old buffer and swap in temporary
  13.         delete[] arrayPointer;
  14.         arrayPointer = temp;
  15.  
  16.         // arraySize stays the same of course
  17.  
  18.         // return a reference to the current (modified) string
  19.         return *this;
  20. }
Now the pointer/memory allocation/deallocation stuff is 'hidden' inside the string class. This is good since encapsulation is the main goal of OO languages (not code reuse as many people think). To reverse a string you can now do it like this:
cpp Code:
Original - cpp Code
  1. AltString newString('a');
  2. newString.reverse(); // newString is now reverse (I know 'a' is not really exciting to reverse, you get the point
  3. AltString otherString = newString.reverse(); // otherString is a copy of newString in reverse
  4. newString.reverse().reverse().reverse().reverse();   // this works too, although it makes more sense if you add in concat() or other functions
  5.  

You won't need to explicitly delete anything now and you do not have a memory leak (well at least the previous one is gone, I have not checked for more). The AltString class behaves like a 'value type' now.

p.s. Code untested since I do not have a compiler at hand. It also not thread-safe, but that is a more advanced topic. It also does not check if length() > 0 or if arrayPointer is a valid pointer etc.

Reply With Quote
  #12  
Old September 21st, 2008, 01:03 PM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
By the way, to see why the default-generated assignment operator is wrong do the following test:
cpp Code:
Original - cpp Code
  1. AltString s1('a');
  2. AltString s2 = s1;
  3. s2.setAt(0, 'b');
  4. s1.display();
  5. s2.display();

s1 should print a, and s2 should print b right?

Reply With Quote
  #13  
Old September 21st, 2008, 01:05 PM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
I see you added a link to the project. I think I was right, both concat() and reverse() instruct you to change/return 'this' string. I am signing of for today. If you want more help I am happy to look at it tomorrow, good luck

Reply With Quote
  #14  
Old September 21st, 2008, 01:06 PM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Wow, that actually makes a lot of sense and makes the code simpler
One of the problems I have is identifying where there would be a leak of some sort. For example, does toUpper and toLower function leak? I'd say no since I am just changing what the current array holds, but then again I am not too sure.
Would you be so kind as to list which functions of mine have memory leaks?

Much appreciated

Reply With Quote
  #15  
Old September 21st, 2008, 04:25 PM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
toUpper and toLower do not leak since you are not calling 'new' anywhere (not even indirectly). On quick inspection, concat, reverse, and substring might have a leak, in the way that I explained before for reverse().

Next to that the assignment states that your compare function should be a friend function not a member function. Also the copy constructor which takes a const char*& is having the same problem as the other copy constructor, the internal buffer is uninitialised, you should do a new there somewhere. And charAt() is not returning the null character if the length of the string is 0.

You should think about these things yourself of course. Usually I don't help that much with people's exercises. It really pays off to figure things out yourself. But I do not think you just want me to do your exercise, I think you want to learn. You should try to make some tests for your class, really think about what the class should be able to do, at least on test for each requirement in the assignment. Then start testing your class with them so you can find the errors.

Reply With Quote
  #16  
Old September 21st, 2008, 05:17 PM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Hmm... interesting...
So I went back and changed the program around, mostly on Copy, SubString, and Concat and imitated what you did in Reverse().

So now the program looks like:

Code:
#include <iostream>
#include "AltString.h"
using namespace std;

AltString::AltString()
{
        arrayPointer = new char[1];
        setArraySize(1);
}

AltString::AltString(char ch)
{
        arrayPointer = new char[1];
        setAt(0, ch);
        setArraySize(1);
}

AltString::AltString(int size)
{
        arrayPointer = new char[size];
        setArraySize(size);
}

AltString::AltString(const AltString& otherAltString)
{
        setArraySize(otherAltString.length());
        arrayPointer = new char[otherAltString.length()];
        for(int i = 0; i < otherAltString.length(); i++)
        {
                setAt(i, otherAltString.charAt(i));
        }
}

AltString::AltString(const char*& nullTermString)
{
        int index = 0;
        while(true)
        {
                int i = 0;
                if(nullTermString[i] == '\0')
                {
                        index = i;
                }
                i++;
        }
        for(int j = 0; j < index; j++)
        {
                setAt(j, nullTermString[j]);
        }
        setArraySize(index);
}

AltString::~AltString()
{
        delete[] arrayPointer;
        setArraySize(0);
}

int AltString::compare(const AltString& stringA, const AltString& stringB)
{
        bool isEqual = false;
        int shorterLength = 0;
        if(stringA.length() > stringB.length())
        {
                shorterLength = stringA.length();
        }
        else if(stringA.length() < stringB.length())
        {
                shorterLength = stringB.length();
        }
        else
        {
                shorterLength = stringA.length();
                isEqual = true;
        }
        for(int i = 0; i < shorterLength; i++)
        {
                int x = stringA.charAt(i);
                int y = stringB.charAt(i);
                if(x < y)
                {
                        return -1;
                }
                else if(x > y)
                {
                        return 1;
                }
        }
        if(isEqual)
        {
                return 0;
        }
        if(stringA.length() < stringB.length())
        {
                return -1;
        }
        else
        {
                return 1;
        }
}

char AltString::charAt(int index) const
{
        if(index < 0)
        {
                index = 0;
        }
        else if(index > length() - 1)
        {
                index = length() - 1;
        }
        return arrayPointer[index];
}

AltString& AltString::concat(AltString otherAltString)
{
        int oldLength = length();
        int newLength = length() + otherAltString.length();
        char* temp = new char[newLength];
        setArraySize(newLength);
        for(int i = 0; i < oldLength; i++)
        {
                temp[i] = charAt(i);
        }
        for(int i = 0; i < otherAltString.length(); i++)
        {
                temp[i + oldLength] = otherAltString.charAt(i);
        }
        delete[] arrayPointer;
        arrayPointer = temp;
        return *this;
}

void AltString::display() const
{
        for(int i = 0; i < length(); i++)
        {
                cout << charAt(i);
        }
        cout << endl;
}

int AltString::indexOf(char ch) const
{
        for(int i = 0; i < length(); i++)
        {
                if(charAt(i) == ch)
                {
                        return i;
                }
        }
        return -1;
}

int AltString::length() const
{
        return arraySize;
}

bool AltString::setAt(int index, char ch)
{
        if(index > length() || index < 0)
        {
                return false;
        }
        else
        {
                arrayPointer[index] = ch;
                return true;
        }
}

AltString& AltString::subString(int low, int high) const
{
        /*
        if(high > low)
        {
                if(high > length() - 1)
                {
                        high = length() - 1;
                }
                if(low < 0)
                {
                        low = 0;
                }
                char* temp = new char[high - low + 1];
                setArraySize(high - low + 1);
                for(int i = 0; i < length(); i++)
                {
                        temp[i] = arrayPointer[i];
                }
        }
        else
        {
                char* temp = new char[1];
                setArraySize(1);
        }
        delete[] arrayPointer;
        arrayPointer = temp;
        return *this;
        */

        AltString* newString = new AltString;
        if(high > low)
        {
                if(high > length() - 1)
                {
                        high = length() - 1;
                }
                if(low < 0)
                {
                        low = 0;
                }
                newString->arrayPointer = new char[high - low + 1];
                newString->setArraySize(high - low + 1);
                for(int i = 0; i < newString->length(); i++)
                {
                        newString->setAt(i, charAt(i));
                }
        }
        return *newString;
}

AltString& AltString::toUpper()
{
        for(int i = 0; i < length(); i++)
        {
                int x = charAt(i);
                if(x >= 97 && x <= 122)
                {
                        x = x - 32;
                        char newChar = static_cast<char>(x);
                        setAt(i, newChar);
                }
        }
        return *this;
}

AltString& AltString::toLower()
{
        for(int i = 0; i < length(); i++)
        {
                int x = charAt(i);
                if(x >= 65 && x <= 90)
                {
                        x = x + 32;
                        char newChar = static_cast<char>(x);
                        setAt(i, newChar);
                }
        }
        return *this;
}

AltString& AltString::reverse()
{
        char* temp = new char[length()];
        for(int i = 0; i < length(); i++)
        {
                temp[i] = arrayPointer[length() - 1 - i];
        }
        delete[] arrayPointer;
        arrayPointer = temp;
        return *this;
}

//stringArray functions

void AltString::setArraySize(int newSize)
{
        arraySize = newSize;
}


And I made a tester which looks like:

Code:
#include <iostream>
#include "AltString.h"
using namespace std;

int main()
{
        cout << "\nTest 1:\n" << endl;
        cout << "Normal Constructor" << endl;
        AltString newString;
        cout << "Display Function" << endl;
        newString.display();
        cout << "Should have printed nothing.\n\n" << endl;

        cout<<"Test 2:\n" << endl;
        cout << "Constructor with a char" << endl;
        AltString newString2('a');
        newString2.display();
        cout << "Should have printed a." << endl;
        AltString newString3('b');
        newString3.display();
        cout << "Should have printed b.\n\n" << endl;

        cout << "Test 3:\n" << endl;
        cout << "Concat Function" << endl;
        newString2 = newString2.concat(newString3);
        newString2.display();
        cout << "Should have printed ab." << endl;
        AltString newStringC('c');
        AltString newStringD('d');
        AltString newStringE('e');
        newStringC = newStringC.concat(newStringD);
        newStringC.display();
        cout << "Should have printed cd." << endl;
        newStringC = newStringC.concat(newStringE);
        newStringC.display();
        cout << "Should have printed cde." << endl;
        newString2 = newString2.concat(newStringC);
        newString2.display();
        cout << "Should have printed abcde.\n\n" << endl;

        cout << "Test 4:\n" << endl;
        cout << "Constructor for multisize" << endl;
        AltString newString4(5);
        newString4.display();
        cout << "Should have printed nothing." << endl;
        cout << "SetAt Function" << endl;
        for(int i = 0; i < 6; i++)
        {
                newString4.setAt(i, 'a');
        }
        newString4.display();
        cout << "Should have printed aaaaa.\n\n" << endl;

        cout << "Test 5:\n" << endl;
        cout << "Copy Function" << endl;
        AltString newString5(newString4);
        newString5.display();
        cout << "Should have printed aaaaa.\n\n" << endl;

        cout << "Test 6:\n" << endl;
        cout << "toUpper Function" << endl;
        AltString newString6(3);
        newString6.setAt(0, 'a');
        newString6.setAt(1, 'b');
        newString6.setAt(2, 'c');
        newString6.display();
        cout << "Should have printed abc." << endl;
        newString6.toUpper();
        newString6.display();
        cout << "Should have printed ABC.\n\n" << endl;

        cout << "Test 7:\n" << endl;
        cout << "toLower Function" << endl;
        newString6.toLower();
        newString6.display();
        cout << "Should have printed abc.\n\n" << endl;

        cout << "Test 8:\n" << endl;
        cout << "Reverse Function" << endl;
        AltString newString7 = newString6.reverse();
        newString7.display();
        cout << "Should have printed cba." << endl;
        newString7 = newString7.reverse();
        newString7.display();
        cout << "Should have printed abc.\n\n" << endl;

        /*
        cout << "Test 9:\n" << endl;
        cout << "Compare Function" << endl;
        int result = compare(newString4, newString5);
        cout << result << endl;
        cout << "Should have printed 0." << endl;
        result = compare(newString4, newString6);
        cout << result << endl;
        cout << "Should have printed 1." << endl;
        result = compare(newString, newString4);
        cout << result << endl;
        cout << "Should have printed -1." << endl;
        newString6.toUpper();
        result = compare(newString6, newString7);
        cout << result << endl;
        cout << "Should have printed -1.\n\n" << endl;
        */

        cout << "Test 10:\n" << endl;
        cout << "Substring Function" << endl;
        AltString newString8 = newString4.subString(0, 3);
        newString8.display();
        cout << "Should have printed aaaa." << endl;
        newString8 = newString8.subString(-3, 6);
        newString8.display();
        cout << "Should have printed aaaa." << endl;
        newString8 = newString8.subString(5, 2);
        newString8.display();
        cout << "Should have printed nothing.\n\n" << endl;

        cout << "Test 11:\n" << endl;
        cout << "IndexOf Function" << endl;
        int index = newString6.indexOf('c');
        cout << index << endl;
        cout << "Should have printed 2." << endl;
        index = newString4.indexOf('a');
        cout << index << endl;
        cout << "Should have printed 0." << endl;
        index = newString4.indexOf('b');
        cout << index << endl;
        cout << "Should have printed -1." << endl;

        cout << "End Tester Program." << endl;
        return 0;
}


I realized I am going to have the do a friend function for my compare, but I am not worry about that until I finish debugging concat.
Right now, though, concat is giving me a weird bug:

During test 3:

Code:
        cout << "Test 3:\n" << endl;
        cout << "Concat Function" << endl;
        newString2 = newString2.concat(newString3);
        newString2.display();
        cout << "Should have printed ab." << endl;
        AltString newStringC('c');
        AltString newStringD('d');
        AltString newStringE('e');
        newStringC = newStringC.concat(newStringD);
        newStringC.display(); //DISPLAYS ONLY C
        cout << "Should have printed cd." << endl;
        newStringC = newStringC.concat(newStringE);
        newStringC.display(); //DISPLAYS ONLY CE
        cout << "Should have printed cde." << endl;
        newString2 = newString2.concat(newStringC);
        newString2.display(); //DISPLAYS ONLY ABCE
        cout << "Should have printed abcde.\n\n" << endl;


I don't know why it only does that on newStringD, and that's not the worst. It works properly SOMETIMES... so it's not even consistent. At first I thought it was a memory error, but it can't be if it only works on newStringD. Then I thought something was wrong with my charAt(), but I can't find any error with that as far as I can see, seeing how it works for everything else.

So I am stuck with this inconsistent error, any help would be appreciated. And you are right about learning to do it myself. I am all for example -> doing it myself, but our professor seems to think if we go and fumble in the dark without examples is the right way to go...

Reply With Quote
  #17  
Old September 21st, 2008, 07:27 PM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Problem Resolved.

The issue was that I used setAt() in my constructor (I thought in C++ you can use functions you initialized later in the program, but it seems not), and also instead of using a char* I just went ahead and made an AltString* in concat. It fixed the problem.

Now that the only thing left is taking care of memory leaks in:

Code:
AltString& AltString::concat(AltString otherAltString)
{
        int oldLength = length();
        int newLength = length() + otherAltString.length();
        AltString *newString = new AltString(newLength);
        for(int i = 0; i < oldLength; i++)
        {
                newString->setAt(i, charAt(i));
        }
        for(int i = 0; i < otherAltString.length(); i++)
        {
                newString->setAt(i + oldLength, otherAltString.charAt(i));
        }
        return *newString;
}

AltString& AltString::subString(int low, int high) const
{
        AltString* newString = new AltString;
        if(high > low)
        {
                if(high > length() - 1)
                {
                        high = length() - 1;
                }
                if(low < 0)
                {
                        low = 0;
                }
                newString->arrayPointer = new char[high - low + 1];
                newString->setArraySize(high - low + 1);
                for(int i = 0; i < newString->length(); i++)
                {
                        newString->setAt(i, charAt(i));
                }
        }
        return *newString;
}


How would you take care of the memory leaks in these functions?

And, I need to friend the compare functions:

Code:
int AltString::compare(const AltString& stringA, const AltString& stringB)
{
        bool isEqual = false;
        int shorterLength = 0;
        if(stringA.length() > stringB.length())
        {
                shorterLength = stringA.length();
        }
        else if(stringA.length() < stringB.length())
        {
                shorterLength = stringB.length();
        }
        else
        {
                shorterLength = stringA.length();
                isEqual = true;
        }
        for(int i = 0; i < shorterLength; i++)
        {
                int x = stringA.arrayPointer[i];
                int y = stringB.arrayPointer[i];
                if(x < y)
                {
                        return -1;
                }
                else if(x > y)
                {
                        return 1;
                }
        }
        if(isEqual)
        {
                return 0;
        }
        if(stringA.length() < stringB.length())
        {
                return -1;
        }
        else
        {
                return 1;
        }
}


I've looked at examples, but they friend classes with classes. What I want to do is friend the compare function so my tester can actually see it and such. How would I perform that task?

Reply With Quote
  #18  
Old September 22nd, 2008, 12:35 AM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Okay, I've fixed mostly everything... semantic errors at least. I asked the instructor on memory leak with the =operator, but he said:

"The constructor and destructor for the AltString object take care of allocation
and deallocation of any dynamic data storage for it. You didn't find anything
because you shouldn't have to do anything."

and:

"The destructor is called automatically; don't try to call it yourself.

The problem with = is to make sure you don't assign an object to itself;
that's discussed in the text under overloading the = operator."

So did I do my Constructor and Destructor right?

Code:
AltString::AltString()
{
        arrayPointer = new char[1];
        setArraySize(1);
}

AltString::AltString(char ch)
{
        arrayPointer = new char[1];
        arrayPointer[0] = ch;
        setArraySize(1);
}

AltString::AltString(int size)
{
        setArraySize(size);
        arrayPointer = new char[size];
}

AltString::AltString(const AltString& otherAltString)
{
        setArraySize(otherAltString.length());
        arrayPointer = new char[otherAltString.length()];
        for(int i = 0; i < otherAltString.length(); i++)
        {
                arrayPointer[i] = otherAltString.arrayPointer[i];
        }
}

AltString::AltString(const char*& nullTermString)
{
        int index = 0;
        while(true)
        {
                if(nullTermString[index] == '\0')
                {
                        break;
                }
                index++;
        }
        arrayPointer = new char[index];
        setArraySize(index);
        for(int i = 0; i < index; i++)
        {
                arrayPointer[i] = otherAltString.arrayPointer[i];
        }
}

AltString::AltString(const char*& nullTermString)
{
        int index = 0;
        while(true)
        {
                if(nullTermString[index] == '\0')
                {
                        break;
                }
                index++;
        }
        arrayPointer = new char[index];
        setArraySize(index);
        for(int i = 0; i < index; i++)
        {
                arrayPointer[i] = nullTermString[i];
        }
}

AltString::~AltString()
{
        delete[] arrayPointer;
        setArraySize(0);
}


As for the subString function, it seems like I've ran into something weird:

Code:
AltString& AltString::subString(int low, int high) const
{
        AltString* newString = new AltString;
        if(high > low)
        {
                if(high > length() - 1)
                {
                        high = length() - 1;
                }
                if(low < 0)
                {
                        low = 0;
                }
                newString->setArraySize(high - low + 1);
                newString->arrayPointer = new char[high - low + 1];
                for(int i = 0; i < newString->length(); i++)
                {
                        newString->arrayPointer[i] = arrayPointer[i];
                }
        }
        return *newString;
}


Tester:

Code:
        cout << "Test 10:\n" << endl;
        cout << "Substring Function" << endl;
        AltString newString8 = newString4.subString(0, 3);
        newString8.display();
        cout << "Should have printed aaaa." << endl;
        newString8.subString(-3, 6);
        newString8.display();
        cout << "Should have printed aaaa." << endl;
        newString8.subString(5, 2);
        newString8.display();
        cout << "Should have printed nothing.\n\n" << endl;


So in order, it should display:

aaaa
aaaa
//Nothing

Yet it is displaying:
aaaa
aaaa
aaaa

I can't see the error for this so any help would be appreciated !

Reply With Quote
  #19  
Old September 22nd, 2008, 02:11 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Your constructor and destructor seem ok to me. The destructor is automatically called for any object created in auto storage. (i.e., created like: AltString s('a'); ). Objects created in the freestore using 'new' are _not_ automatically destroyed.

I don't know what your instructor thinks but I am fairly sure the assignment operator generated by the compiler is wrong in this case. Maybe the instructor thought you have a different implementation, but with this one you will end up with problems. In most of your testing programs you are assigning references so you won't see any of the problems there. There is actually no memory leak with the operator= but you will get two strings referencing the same buffer and you will thus get a double delete.

I will have a deeper look later at the code, I am at work now.. For many (all?) of the function you do not need to create a new AltString inside the function, you should just recreate the arrayPointer, and even that is not necessary in most of them.

Reply With Quote
  #20  
Old September 22nd, 2008, 03:48 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
To be honest I don't think substring can be done in a proper way if you cannot modify the string and still want to return a reference.

What is happening for you in substring is that you are creating a new AltString and returning a reference to that. So
Code:
newString8.subString(0,3)

is returning the substring, but you are not storing it in any variable. newString8 always stays unchanged. So you are printing newString8 three times without modifying it.

(I still think your concat is not correct, you are not modifying the string there either)

Reply With Quote
  #21  
Old September 22nd, 2008, 04:05 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
The substring signature is flawed, it should be:
Code:
AltString subString(int low, int high) const

instead of
Code:
AltString& subString(int low, int high) const

Reply With Quote
  #22  
Old September 22nd, 2008, 08:45 AM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Quote:
(I still think your concat is not correct, you are not modifying the string there either)


This is my updated Concat, forgot to post that.
Code:
AltString& AltString::concat(AltString otherAltString)
{
        int oldLength = length();
        int newLength = length() + otherAltString.length();
        char* temp = new char[newLength];
        setArraySize(newLength);
        for(int i = 0; i < oldLength; i++)
        {
                temp[i] = arrayPointer[i];
        }
        for(int i = 0; i < otherAltString.length(); i++)
        {
                temp[i + oldLength] = otherAltString.arrayPointer[i];
        }
        delete[] arrayPointer;
        arrayPointer = temp;
        return *this;
}


Quote:
The substring signature is flawed, it should be:


Sadly, I can't change any signature given to me by the instructor. I emailed him and asked him about this problem, but he hasn't emailed me back. He might say they only invoke str1 = str1.subStr(str2) in the tester, but I'll have to see. I'll keep you updated

Quote:
Objects created in the freestore using 'new' are _not_ automatically destroyed.


How would I destroy these objects properly?

UPDATE:

My instructor emailed me back saying:

"That's correct. The original string is unchanged, so if you want to
save the substring it needs to be assigned to something (itself, or some
other AltString)."

So I am guessing he wants AltString creation inside the func. I wonder how I would handle the memory leak from using that though.... or if he tests it at all...

Reply With Quote
  #23  
Old September 22nd, 2008, 09:06 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
The concat looks ok to me now (Although I would make the parameter a const AltString& because the concat now makes redundant copies)

Objects created with 'new' are not automatically destroyed and you need to explicitly delete them, i.e., delete ptr; or delete[] arrayPtr; or something similar.

Your instructor:
"That's correct. The original string is unchanged, so if you want to
save the substring it needs to be assigned to something (itself, or some
other AltString)."

I think your instructor is losing it, substring is 'const' qualified so you cannot save it in 'itself'. If any 'other' AltString is created using new you will have a potential memory leak. In the end you should not return a AltString& if it does not reference 'this'. The return value should be a AltString, i.e., a copy.

If your instructor is not convinced let him look at the std::string implementation, std::string::substr() also returns by value.

I have made a small test implementation of AltString myself (I have a boring task at work atm). I will post it if you have more trouble with your instructor ;-)

I would really like to know how your instructor is testing the substring. It would not be the first time that I spot real errors in tutorial/university code.

Reply With Quote
  #24  
Old September 22nd, 2008, 12:54 PM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Quote:
Me: I am assuming for subString we have to make a whole new AltString to containg the SubString that was obtained.
How would we take care of memory leaks then? Someone told me something about program crashing due to = operation and deleting the same memory twice... I know you mention something about the destructor, but does the destructor used in this case inside the subString func? Do we manually call it or not? I remember the TA saying something about no need to manually call it.

Instructor: The destructor is called automatically; don't try to call it yourself.

The problem with = is to make sure you don't assign an object to itself;
that's discussed in the text under overloading the = operator.


So I am assuming I can't do something like str1 = str1.subStr(low, high) but instead have to do something like str2 = str1.subStr(low, high).
I have no idea why the instructor is asking us to do this. It's easier for me to code if the AltString in the parameter is not const, and it's easier for the user. But since the instructor is asking us to do this, then I'll go ahead and do it. But would doing something like str2 = str1.subStr(low, high) still cause a memory leak?

Reply With Quote
  #25  
Old September 23rd, 2008, 02:53 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Ok, _my_ subString would look something like this:
cpp Code:
Original - cpp Code
  1.    AltString subString( int low, int high ) const
  2.    {
  3.       if( high <= low )
  4.       {
  5.          return AltString();
  6.       }
  7.       else
  8.       {
  9.          size_t start = boundsCheck( low ); // boundscheck is a private function checking param<0 || param >= length_
  10.          size_t end = boundsCheck( high );
  11.  
  12.          AltString newSubString;
  13.          newSubString.length_ = high-low;
  14.          newSubString.buffer_ = new char[ newSubString.length_ ];
  15.  
  16.          std::copy( buffer_ + low, buffer_ + high, newSubString.buffer_ );
  17.  
  18.          return newSubString;
  19.       }
  20.    }

I am almost thinking you could use this one and your instructor will not even see any difference (except that it works properly..).

<EDIT> I just don't know what your instructors wants

You should add some print statements to the constructor, copy constructor, destructor, and assignment operator (operator= ) and then see what happens.

P.s., it is ok to directly use the member variables inside the function of the class. Actually, using the public functions (setAt(), length()) etc, makes it harder to maintain the class.

Last edited by Icon : September 23rd, 2008 at 07:46 AM.

Reply With Quote
  #26  
Old September 23rd, 2008, 06:24 AM
MaHuJa's Avatar
MaHuJa MaHuJa is offline
Contributing User
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Dec 2007
Posts: 1,177 MaHuJa User rank is Private First Class (20 - 50 Reputation Level)MaHuJa User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 1 Week 1 Day 21 h 27 m 36 sec
Reputation Power: 12
Send a message via Skype to MaHuJa Send a message via XFire to MaHuJa
cpp Code:
Original - cpp Code
  1.    AltString& AltString::subString(int low, int high) const
  2.    {
  3.       AltString newString;
  4. .....
  5.       return newString;
  6.    }


Baad idea. Very bad.

The object will be outside its lifetime by the time you try to use it in the caller.
a) The destructor has been run. The data area has probably been deallocated.
b) The thing may be overwritten at any time - particularly if there is another function call involved.

Reply With Quote
  #27  
Old September 23rd, 2008, 07:44 AM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
I am not sure you read the whole thread.. That is exactly what I am telling him not to do. You can see the version I proposed returns the string by copy. But his instructor insists on returning it by reference.

Creating a pointer inside the function and returning that, dereferenced, by reference (you get what I mean ) is almost just as bad though.

Maybe I should not have shown the code which was 'closest' to proper but still dead-wrong.. (Although without a memory leak..)

Reply With Quote
  #28  
Old September 23rd, 2008, 12:00 PM
MaHuJa's Avatar
MaHuJa MaHuJa is offline
Contributing User
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Dec 2007
Posts: 1,177 MaHuJa User rank is Private First Class (20 - 50 Reputation Level)MaHuJa User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 1 Week 1 Day 21 h 27 m 36 sec
Reputation Power: 12
Send a message via Skype to MaHuJa Send a message via XFire to MaHuJa
I did read, at least skimmed, most of it - and I'm not thinking that you actually proposed doing this, that much was clear from your post.

If it really has to be by reference (I too find that a very dubious design decision), I would suggest a static variable (iow to h with thread safety) like the winsock long (0xffffffff) to (c)string ("255.255.255.255") function. Alternatively you could use some sort of pool (std::deque<string*>), but unless you empty the pool (deleting every string you've made) every now and then, it won't be destroyed before the program quits anyway, at which point it doesn't really matter for a resource that's only hogging memory.

Quote:
So I am assuming I can't do something like str1 = str1.subStr(low, high) but instead have to do something like str2 = str1.subStr(low, high).


If you return by value, s1=s1.substr(a,b) is perfectly valid, since s1.substr() returns a separate, unnamed value. ("temporary")

Reply With Quote
  #29  
Old September 23rd, 2008, 02:34 PM
AuraofMana AuraofMana is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2008
Posts: 28 AuraofMana User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 11 sec
Reputation Power: 0
Despite how wrong it is, my instructor assured me that there are no memory leaks and I don't need to do anything to do it. AND, doing it with creating a new AltString then returning *of it is the correct way. So I just sent mine in as he depicted, since I only get the grade if I actually followed the project requirement.
He said the destructor would be automatically be called by the program and clean up that memory, but I am skeptical. But alas, he's teaching the class, so I am just going to go along with his requirements.
I already submitted by proj (was due 1 min before midnight last night), but I would have never finished it without your help. Thanks a lot for your help, Icon!

(Is so going to bug Icon again when the next project comes and problem happens).

Reply With Quote
  #30  
Old September 23rd, 2008, 02:42 PM
Icon's Avatar
Icon Icon is offline
Command Line Warrior
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: Sep 2005
Posts: 1,021 Icon User rank is Private First Class (20 - 50 Reputation Level)Icon User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 2 Weeks 8 h 12 m 36 sec
Reputation Power: 15
Seriously, the objects created with new will not be automatically destroyed, your instructor is wrong.. Anyway I hope you get the points. I like helping people who want to learn.

I will prepare a little test program for you today or tomorrow. If you're really interested it learning you should try to run it. In the end I guess you really want to know how to program and not just make your instructor happy

p.s. of course all the memory gets reclaimed by the OS when the program(process) exits, maybe your instructor means that. But the destructor is _not_ automatically called at process exit for objects on the heap ( = created with new).

Reply With Quote
Reply

Viewing: Dev Articles Community ForumsProgrammingC/C++ Help > Weird Segmentation Fault


Developer Shed Advertisers and Affiliates


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap