Link to home
Start Free TrialLog in
Avatar of kuntilanak
kuntilanakFlag for United States of America

asked on

terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc

Why am I getting the error above?  For the following code and test:

String operator/(const String& str, int n){
      String r('x', n);
      if (n > 0){
            for (int i = 0; i < n; i++)
                  r[i] = str[i];
      }else if (n < 0){
            for (int i = str.length()+n; i < str.length()-1; i++){
                  r[i] = str[i];      
            }
      }
      return r;
}

 String lets = "abcdefg";
  String sfx = lets / -2;



#include <cstring>
#include <cstdio>
#include <cassert>
#include <cctype>

#include "String.h"

String::String()
{
    itsPtr = new char[1];
    itsPtr[0] = '\0';
}

String::String(const char *s)
{
    itsPtr = new char[strlen(s) + 1];
    strcpy(itsPtr, s);
}

String::String(char c)
{
    itsPtr = new char[2];
    itsPtr[0] = c;
    itsPtr[1] = '\0';
}

String::String(char c, int n)
{
    itsPtr = new char[n+1];
    for (int i = 0; i < n; i++)
    	itsPtr[i] = c;
    itsPtr[n] = '\0';
}

String::~String()
{
    delete [] itsPtr;
}

String& String::operator=(const char c){
	 String r(c);
	 strcpy(itsPtr, r.itsPtr);
	 return *this;
}

String& String::operator=(const String& rhs)
{
    if (this != &rhs) { // know myself
        delete [] itsPtr;
        itsPtr = new char[strlen(rhs.itsPtr)+1];
        strcpy(itsPtr, rhs.itsPtr);
        }
    return *this;
}

String::String(const String& s)
{
    itsPtr = new char[strlen(s.itsPtr) + 1];
    strcpy(itsPtr, s.itsPtr);
}

String String::operator-(){
	String r('x', strlen(itsPtr));
	int i, j = 0;
	for(i = r.length()-1; j < r.length(); j++, i--)
		r[j] = itsPtr[i];
	return r;
}

String String::operator!(){
	String r('x', strlen(itsPtr));
	for(int i = 0; i < r.length(); i++)
		r[i] = toupper(itsPtr[i]);
	return r;
}

String operator*(int n, const String& str){
	String r;
	assert(n >= 0);
	if (n > 0){
		for (int i = 0; i < n; i++)
		r = r + str;
	}
	return r;
}

String operator*(const String& str, int n){
	return operator*(n, str);
}

String operator/(const String& str, int n){
	String r('x', n);
	if (n > 0){
		for (int i = 0; i < n; i++)
			r[i] = str[i];
	}else if (n < 0){
		for (int i = str.length()+n; i < str.length()-1; i++){
			r[i] = str[i];	
		}
	}
	return r;
}

String operator+(const String& lhs, const String& rhs)
{
    int len = lhs.length() + rhs.length();

    char *p = new char[len + 1];

    strcpy(p, lhs.ptr());
    strcat(p, rhs.ptr());

    String r(p); // Invokes String(const char *)
    delete [ ] p;

    return r;
}

char& String::operator[ ](int pos)
{
    assert(pos >= 0 && pos < strlen(itsPtr));
    return itsPtr[pos];
}

void String::dump(const char *label)
{
    printf("%s: '%s' (at %p)\n", label, itsPtr, itsPtr);
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
soz evilrix ;)
since the negative value will be converted to a size_t and since this type is unsigned it'll result in a huge number that will probably cause allocation to fail, hence the exception.
>> soz evilrix ;)
Heh. No worries chap.
Avatar of kuntilanak

ASKER

okay I fixed my constructor so that it takes negative value, but then still it generates a problem with me access overload.

The assertion always fails
String operator/(const String& str, int n){
	String r('x', n);
	if (n > 0){
		for (int i = 0; i < n; i++)
			r[i] = str[i];
	}else if (n < 0){
		for (int i = str.length()+n; i < str.length(); i++)
			r[i] = str[i];	
	}
	return r;
}

char& String::operator[ ](int pos)
{
    assert(pos >= 0 && pos < strlen(itsPtr));
    return itsPtr[pos];
}

Open in new window

>> but then still it generates a problem with me access overload.

Well, you're asserting n is always positive are you not? Is it?
that is true, but n inside the loop it is always positive
>> that is true, but n inside the loop it is always positive
So if that's always true what about the other side of the and? Is the length always greater than n? One of those expressions must be false. Why don't you do them as two separate asserts? Since an assert costs nothing at run time it's more useful to separate them out.
>> Since an assert costs nothing at run time it's more useful to separate them out.
Sorry, that was meant to say, at run time in a release build
I think it's supposed to be
String operator/(const String& str, int n){
	String r('x', n);
	if (n > 0){
		for (int i = 0; i < n; i++)
			r[i] = str[i];
	}else if (n < 0){
		int j = 0;
		for (int i = str.length()+n; i < str.length(); i++, j++)
			r[j] = str[i];	
	}
	return r;
}

Open in new window

but testing this with:

 String lets = "abcdefg";
  String sfx = lets / -2;

gives me fg and a weird character
What is it mean to give you? As I8 said above, "You are seriously abusing operator overloading" and the semantics of  this expression are unclear to me.