473,399 Members | 3,401 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Runtime error: std::bad_alloc at memory location

Hi,

I have the following code snippets and I get a std::bad_alloc error
where I think there should be none. I've attached the relevant bits of
the base class, derived class and the .cpp file containing the main()
method.

I'd really appreciate any help in getting this error sorted out.

Thanks,
Anuj
Base class:

onst int DESCRIPTION_LENGTH = 128;

class InventoryItem {

private:
char* itemDescription;
int itemQuantity;
double itemCost;

void assignDescription(const char* desc) {
int stringLength = strlen(desc);
itemDescription = new char[stringLength + 1];
strncpy(itemDescription, desc, DESCRIPTION_LENGTH);
}

public:
// Constructor
InventoryItem(const char* desc, int qty, double cost) {
assignDescription(desc);
itemQuantity = qty;
itemCost = cost;
}

// Destructor
~InventoryItem(void) {
delete [] itemDescription;
}
}

Derived class:

const int DEFAULT_SIZE = 20;

class InventoryList {

private:
InventoryItem **inventory;
int count;

public:
// Constructor
InventoryList(void) {
inventory = new InventoryItem*[DEFAULT_SIZE];
count = 0;
}
// Destructor
~InventoryList(void) {
for (int i = 0; i < count; i++)
delete inventory[i];
delete [] inventory;
}

// Method to add InventoryItem object to InventoryList object
void addItem(InventoryItem* item) {
inventory[count++] = item;
}
}

Main .cpp:

#include "InventoryItem.h"
#include "InventoryList.h"
#include <iostream>

using namespace std;

int main(void)
{
InventoryList* inventory = new InventoryList[10];

inventory->addItem(new InventoryItem("wrench", 3, 21.99));
inventory->addItem(new InventoryItem("hammer", 9, 1.99));
inventory->addItem(new InventoryItem("pliers", 2, 2.99));
inventory->addItem(new InventoryItem("saw", 6, 3.99));

inventory->printList();

return 0;
}

Nov 11 '06 #1
3 18059
schizoid_man wrote:
...
I have the following code snippets and I get a std::bad_alloc error
where I think there should be none. I've attached the relevant bits of
the base class, derived class and the .cpp file containing the main()
method.
One can find many obvious and potential problems with your code if one
assumes that this is a _complete_ code. I will assume that this is just
a fragment, so I'll consider only the problems with the code that is
explicitly present here.

Also, I don't see any "base" and "derived" classes in your code. You
have two unrelated (from the language point of view) classes. Anyway...
>
Base class:
It is not really a "base" for anything in the quoted code...
onst int DESCRIPTION_LENGTH = 128;
const int?
>
class InventoryItem {

private:
char* itemDescription;
int itemQuantity;
double itemCost;

void assignDescription(const char* desc) {
int stringLength = strlen(desc);
itemDescription = new char[stringLength + 1];
strncpy(itemDescription, desc, DESCRIPTION_LENGTH);
Here you allocate 'stringLength + 1' bytes of memory, but then you copy
up to 'DESCRIPTION_LENGTH' bytes into the allocated block. Remember,
this 'strncpy' will _always_ overwrite 'DESCRIPTION_LENGTH' bytes in the
target memory block, even it the source string is shorter than that. In
case when 'desc' is shorter, the 'strncpy' won't stop, but rather it
will fill the remaining bytes of the destination block with zeros.

In other words, here you have a clear case of memory overrun - a very
real reason of undefined behavior, which can easily lead to the
'bad_alloc' exception. 'strncpy' is not what you need in this case. In
this case you can safely use 'strcpy' instead. (Frankly, I don't
understand why you even need that 'DESCRIPTION_LENGTH' in your code).

Better yet, get rid of manual memory management and learn to use
'std::string' instead.
}

public:
// Constructor
InventoryItem(const char* desc, int qty, double cost) {
assignDescription(desc);
itemQuantity = qty;
itemCost = cost;
}

// Destructor
~InventoryItem(void) {
delete [] itemDescription;
}
}
Derived class:
It is not really "derived"...
const int DEFAULT_SIZE = 20;

class InventoryList {

private:
InventoryItem **inventory;
int count;

public:
// Constructor
InventoryList(void) {
'void' is not required here (as well as in other functions)... But
that's a matter of personal preference.
inventory = new InventoryItem*[DEFAULT_SIZE];
count = 0;
}
// Destructor
~InventoryList(void) {
for (int i = 0; i < count; i++)
delete inventory[i];
delete [] inventory;
}

// Method to add InventoryItem object to InventoryList object
void addItem(InventoryItem* item) {
inventory[count++] = item;
Since you don't grow your memory, it makes sense to check for the array
size here. Make sure you don't go over 'DEFAULT_SIZE' elements.

Or, better yet, learn to use 'std::vector<>' instead of allocating
arrays with 'new[]'.
}
}
Main .cpp:

#include "InventoryItem.h"
#include "InventoryList.h"
#include <iostream>

using namespace std;

int main(void)
{
InventoryList* inventory = new InventoryList[10];
Hm... You allocate an array of 10 'InventoryList's but use only the
first element later. What was the point of allocating 10 of them?
Although this is not a reason for the exception...
inventory->addItem(new InventoryItem("wrench", 3, 21.99));
inventory->addItem(new InventoryItem("hammer", 9, 1.99));
inventory->addItem(new InventoryItem("pliers", 2, 2.99));
inventory->addItem(new InventoryItem("saw", 6, 3.99));

inventory->printList();

return 0;
}
Aside from missing 'delete[]' (and no implementation for 'printList')
this 'main' looks fine. The most likely reason for the exception is that
'strncpy' in 'assignDescription'.

--
Best regards,
Andrey Tarasevich

Nov 11 '06 #2
schizoid_man wrote:
Hi,

I have the following code snippets and I get a std::bad_alloc error
where I think there should be none. I've attached the relevant bits of
the base class, derived class and the .cpp file containing the main()
method.

I'd really appreciate any help in getting this error sorted out.

Thanks,
Anuj
Base class:

onst int DESCRIPTION_LENGTH = 128;
I assume u mean "c"onst
>
class InventoryItem {

private:
char* itemDescription;
int itemQuantity;
double itemCost;

void assignDescription(const char* desc) {
int stringLength = strlen(desc);
itemDescription = new char[stringLength + 1];
strncpy(itemDescription, desc, DESCRIPTION_LENGTH);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
This is your error. You're copying more bytes than allocated.
}

public:
// Constructor
InventoryItem(const char* desc, int qty, double cost) {
assignDescription(desc);
itemQuantity = qty;
itemCost = cost;
}

// Destructor
~InventoryItem(void) {
delete [] itemDescription;
}
}
// needs a ";"
>
Derived class:

const int DEFAULT_SIZE = 20;

class InventoryList {

private:
InventoryItem **inventory;
int count;

public:
// Constructor
InventoryList(void) {
inventory = new InventoryItem*[DEFAULT_SIZE];
count = 0;
}
// Destructor
~InventoryList(void) {
for (int i = 0; i < count; i++)
delete inventory[i];
delete [] inventory;
}

// Method to add InventoryItem object to InventoryList object
void addItem(InventoryItem* item) {
inventory[count++] = item;
}
}
needs another ";"
>
Main .cpp:

#include "InventoryItem.h"
#include "InventoryList.h"
#include <iostream>

using namespace std;

int main(void)
{
InventoryList* inventory = new InventoryList[10];

inventory->addItem(new InventoryItem("wrench", 3, 21.99));
inventory->addItem(new InventoryItem("hammer", 9, 1.99));
inventory->addItem(new InventoryItem("pliers", 2, 2.99));
inventory->addItem(new InventoryItem("saw", 6, 3.99));

inventory->printList();
// function does not exist
>
return 0;
}
Give up on cstrings already... Use std::string and std::vector.

e.g.
#include <string>
#include <vector>

class InventoryItem {

private:
std::string itemDescription;
int itemQuantity;
double itemCost;

void assignDescription(const char * desc)
{
itemDescription = desc;
}

public:
// Constructor
InventoryItem(const char* desc, int qty, double cost)
: itemDescription( desc ),
itemQuantity( qty ),
itemCost( cost )
{
}
};

//Derived class:

const int DEFAULT_SIZE = 20;

class InventoryList {

private:
std::vector< InventoryItem inventory;
int count;

public:
// Constructor
InventoryList(void)
{
}

// Destructor
~InventoryList(void) {
}

// Method to add InventoryItem object to InventoryList object
void addItem(const InventoryItem& item)
{
inventory.push_back( item );
}
};

//Main .cpp:

//#include "InventoryItem.h"
//#include "InventoryList.h"
#include <iostream>

using namespace std;

int main(void)
{
InventoryList* inventory = new InventoryList[10];

inventory->addItem(InventoryItem("wrench", 3, 21.99));
inventory->addItem(InventoryItem("hammer", 9, 1.99));
inventory->addItem(InventoryItem("pliers", 2, 2.99));
inventory->addItem(InventoryItem("saw", 6, 3.99));

// inventory->printList();

return 0;
}


Nov 12 '06 #3
Gianni Mariani wrote:
> void assignDescription(const char* desc) {
int stringLength = strlen(desc);
itemDescription = new char[stringLength + 1];
strncpy(itemDescription, desc, DESCRIPTION_LENGTH);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
Thank you both Gianni and Andrey. Replacing strncpy with strcpy did the
trick. As you'd noted, the code was not complete, but I thought I'd just
attach the relevant bits.

Thanks for the tip on <stringand <vector>. I'm going to take a look at
using both.
Nov 12 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: abhilash agarwal | last post by:
hi all!! pl help me i m getting a run time error "memory address .... refer to this location....... memory could not be written at this location....." ..... means some memory address when...
5
by: Asfand Yar Qazi | last post by:
Hi, Just wondering, if I do a: std::set_new_handler(std::terminate) I won't have to worry about a std::bad_alloc being thrown when I do a 'new ...' or a 'new(nothrow) ...', right? Its...
5
by: He Shiming | last post by:
Hi, I have a question regarding memory consumption of class/object member functions. Say that I have: class A { char szAbc; char* getString(); }
2
by: Mark | last post by:
Hello. I have developed a custom webbrowser for my son with features like group browsing etc. So far so good. The program works fine. But then, when I look into the memory usage the programme is...
14
by: Mohsen | last post by:
Hello everyone, In my program, I have to define many pointers and when I want to compile my program (in UNIX), it gives me the following error: terminate called after throwing an instance of...
4
by: sndive | last post by:
Do linux kernels 2.4 and 2.6 have some stash of memory set aside to handle paging in std::bad_alloc or ... exception handling code when new or new throws that exception? How is that handled? Does...
1
by: Curten | last post by:
Hi, When I run a program I have made, i get this error message sometimes: "Application error:The instruction at '...' referenced memory at '...'. Memory could not be "read"..." Are there...
3
jhardman
by: jhardman | last post by:
I was in the middle of troubleshooting a different problem when my web service stopped working with a very cryptic error message: "specified cast is not valid" The only location info is that the...
2
by: itxharsh | last post by:
The error during run time is:"Your code has stopped its execution with a non-zero (failure) exit value.This is generally due to run time Exceptions like Memory Access Violation and Floating Point...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.