[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 608
  • Last Modified:

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

0
kuntilanak
Asked:
kuntilanak
  • 7
  • 4
  • 2
2 Solutions
 
evilrixSenior Software Engineer (Avast)Commented:
what does the constructor of string do if n is negative?
0
 
Infinity08Commented:
You are seriously abusing operator overloading lol. A division operator for a string ?

Anyway ...

It seems like you just want to take a substring, right ?
Note that the block for (n < 0) should probably have the for loop like this :

>>                 for (int i = str.length()+n; i < str.length(); i++){


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

If n is < 0, and then you do this :

>>         String r('x', n);

then the String constructor will do this :

>>     itsPtr = new char[n+1];

If n < -1, then you'll try to allocate memory for a negative amount of characters ... How is that supposed to work ?
0
 
Infinity08Commented:
soz evilrix ;)
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
evilrixSenior Software Engineer (Avast)Commented:
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.
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> soz evilrix ;)
Heh. No worries chap.
0
 
kuntilanakAuthor Commented:
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

0
 
evilrixSenior Software Engineer (Avast)Commented:
>> but then still it generates a problem with me access overload.

Well, you're asserting n is always positive are you not? Is it?
0
 
kuntilanakAuthor Commented:
that is true, but n inside the loop it is always positive
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> 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.
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> 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
0
 
kuntilanakAuthor Commented:
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

0
 
kuntilanakAuthor Commented:
but testing this with:

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

gives me fg and a weird character
0
 
evilrixSenior Software Engineer (Avast)Commented:
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.
0

Featured Post

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

  • 7
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now