I am trying to do some practice for memory allocation.
I have the below code which is working but have two questions.
Where do I have to use delete [ ] to free the memory after allocating?
Why is the output for this code at function when using show() function is CDcar?.
#include <cstdlib>
#include <new>
#include <iostream>
#include <cstring>
using namespace std;
class automobile {
private:
char (*function)[30];
char *type;
double speed;
public:
automobile ( );
automobile (double , char *);
void speed_up (double);
void speed_down(double);
const char * get_function ( ) const;
void show ( );
};
automobile::automobile ( ) {
speed = 0;
function = new char [1][30];
strcpy(function[1], "CD player with MP3");
type = new char [4];
strcpy(type, "car");
}
automobile::automobile(double spd, char * fn ) {
int sz;
}
void automobile::show ( ) {
cout << "This is a " << type << " and it has the following functions: " << function[1] << ", and its speed is " << speed << " km/h\n";
}
int main ( ) {
automobile car;
car.show ( );
return 0;
}
this is the output:
This is a car and it has the following functions: CDcar, and its speed is 0 km/h
I thought the output shoud be this:
This is a car and it has the following functions: CD player with MP3, and its speed is 0 km/h
Please advise
Where do I have to use delete [ ] to free the memory after allocating?
Ideally nowhere. new and delete are features of C++ that are not suitable for most code. They are error-prone and too low-level. They're only useful for basic building blocks.
The code shown could benefit from basic building blocks like std::string, std::vector.
The code shown also invokes undefined behaviour at least in one place:
function = new char [1][30];
strcpy(function[1], "CD player with MP3");
Arrays are 0-based, so function[1] is an out-of-bounds access.
You should call delete[] in the destructor of your class.
//Called when your class is destroyed.
automobile::~automobile()
{
delete[] function;
}
You should place the delete[] for function and type within the destructor ~automobile (you don't have one currently, so you'll have to create it).
Regarding the output: Your character is array is not well defined. Consider using std::vector<string> for such things (much easier).
Your output is incorrect b/c of the following:
speed = 0;
function = new char [1][30];
strcpy(function[1], "CD player with MP3");
This should be
speed = 0;
function = new char [1][30];
strcpy(function[0], "CD player with MP3");
and when you output you should be cout'ing function[0] instead of function[1].
Having said this, you should almost always try to eliminate manual calls to new and delete. It helps with maintainability and it helps keep code exception safe. In this case you can get this for free by using vectors and strings provided by the standard C++ library. In a more general sense, you want to follow the RAII Idiom. This will help C++ and memory management from shaving a couple of years off your life during your studies/career.
Inside ~automobile destructor.
Related
I am new to pointers and I am having trouble in accessing the variables inside a class.
I want to make a sort of database of possible moves in a Chess game, and I think that using pointers is the way to go, since I wouldn't be wasting memory and prevent any unnecessary memory errors.
main.cpp
#include <iostream>
#include "moves.h"
using namespace std;
int main()
{
moves* possibleMoves[100];
&(possibleMoves[0]->piece) = 100;
cout << *&possibleMoves[0]->piece << endl;
return 0;
}
moves.h
#ifndef MOVES_H
#define MOVES_H
class moves
{
public:
moves();
int piece;
int X;
int Y;
int addX;
int addY;
int score;
};
#endif // MOVES_H
Any help would be appreciated. Thank you very much in advance.
Currently it doesn't output anything and I don't know what to do.
I am having trouble in accessing the variables inside a class
It looks like you are making a mess of pointers and references.
There isn't a real need in your code to use array of pointers. Instead using normal array of objects would do.
moves possibleMoves[100];
possibleMoves[0].piece = 100;
cout << possibleMoves[0].piece << endl;
Btw, class moves incorrectly exposes all data members to public - they should be private. And moves constructor needs to be implemented or otherwise should be removed to use the default one.
You are creating an array of pointers with:
moves* possibleMoves[100];
when what you want is an array of moves.
Then you are trying to assign piece in possibleMoves[0] a value of 100 with:
&(possibleMoves[0]->piece) = 100;
but you are actually doing something quite different. As #Henri Menke said best to read up on &, *, . and ->.
To make your intended code work try:
int main()
{
moves possibleMoves[100];
possibleMoves[0].piece = 100;
cout << possibleMoves[0].piece << endl;
return 0;
}
Here you create an array of moves objects, then assign the value of piece in object 0 a value of 100. You retrieve the value and print it to cout.
I am learning C++ and I am having quite a lot of trouble with my current assignment. I have completed a good amount of it so far. However I have been making very slow progress of late due to what I think is my poor understanding of what is going on behind the scenes.
What I am trying to do in the following code is:
Get two separate values (Bullet damage). Done.
Create a dynamic array. Done.
Fill a part (that is the size of a modulus of a random number between 1 and 10) of said dynamic array with one value and the rest with the other in a random order. Here I am having trouble.
Clean up the memory used by said dynamic array. Done.
The error I get is as follows:
Unhandled exception at 0x00a323e3 in Class 3.exe: 0xC0000005: Access
violation reading location 0xcdcdcdcd.
I'm pretty sure that the error occurs when I try to set ammoArray[i] to a value. But I don't know why it's giving it to me, my code compiles fine. I played around with it a bit and in one case I got it to store the memory addresses of bDamage and sDamage and then print out the memory addresses of each element of the array. What I want it to do is store the values held by bDamage and sDamage.
Now for my question:
Why won't ammoArray store the values of bDamage and sDamage instead of the memory addresses of the array's elements? And How do I get it to store them?
Here is my Main.cpp:
#include <cstdlib>
#include "Ammunition.h"
#include "AmmunitionManager.h"
#include "Bullet.h"
#include "Game.h"
#include "Pistol.h"
#include "Player.h"
#include "Point.h"
#include "Shell.h"
#include "Shotgun.h"
#include "WeaponManager.h"
#include "Weapons.h"
using namespace std;
void main()
{
Ammunition amVar;
AmmunitionManager *var = new AmmunitionManager();
amVar.setBDamage(6);
amVar.setSDamage(2);
var->FillAmmoArray(amVar.getSDamage(),amVar.getBDamage());
system("PAUSE");
}
Here is the .h file of the class in question:
#ifndef AMMUNITIONMANAGER_H
#define AMMUNITIONMANAGER_H
#include "Point.h"
#include "Ammunition.h"
class AmmunitionManager
{
public:
AmmunitionManager();
AmmunitionManager(int,int);
~AmmunitionManager();
void FillAmmoArray(int,int);
private:
Ammunition Ammo;
int **ammoArray;
};
#endif
Here is the .cpp file of the class in question:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "AmmunitionManager.h"
#include "Point.h"
#include "Ammunition.h"
using namespace std;
AmmunitionManager::AmmunitionManager()
{
}
AmmunitionManager::AmmunitionManager(int sDamage,int bDamage)
:Ammo(sDamage,bDamage)
{
cout << "Filling ammo reservoir." << endl;
ammoArray = new int* [10];
}
void AmmunitionManager::FillAmmoArray(int sDamage,int bDamage)
{
srand(time(NULL));
int *holdS = &sDamage;
int *holdB = &bDamage;
if(ammoArray)
{
for(int i = 0;i < 9;i++)
{
int randC = rand() % 2 + 1;
if(randC == 1)
{
cout << "Was: " << ammoArray[i] << endl;//I am getting the error here.
ammoArray[i] = holdS;
cout << "Is: " << ammoArray[i] << endl;
}
if(randC == 2)
{
cout << "Was: " << ammoArray[i] << endl;//I am getting the error here.
ammoArray[i] = holdB;
cout << "Is: " << ammoArray[i] << endl;
}
}
}
}
AmmunitionManager::~AmmunitionManager()
{
*ammoArray = 0;
if(ammoArray)
{
delete [] ammoArray;
}
}
Why won't ammoArray store the values of bDamage and sDamage instead of the memory addresses of the array's elements?
Because you said it should store addresses.
Here is a pointer to a pointer:
int **ammoArray;
and here is an array of pointers:
ammoArray = new int* [10];
And How do I get it to store them?
By doing this instead:
int *ammoArray;
and this:
ammoArray = new int [10];
and adjusting FillAmmoArray accordingly.
The default constructor should look like this:
AmmunitionManager::AmmunitionManager()
: ammoArray(nullptr)
{
}
The destructor should look like this:
AmmunitionManager::~AmmunitionManager()
{
delete [] ammoArray;
}
And you should only call srand once.
It's usually done at the beginning of main.
I'm not getting any errors (VS2013). But the values stored are the addresses of sDamage and bDamage.
Did you properly use AmmunitionManager(int sDamage,int bDamage) as a constructor for creating the AmmunitionManager object? From what I'm seeing, you're not.
Apart from that, may I ask why you're using exotic constructs such as **ammoArray instead of e.g. a simple vector<int>? I'm guessing it's part of your assignment, but I'm asking just to make sure I'm not missing anything.
I called the object like this:
int _tmain(int argc, _TCHAR* argv[])
{
AmmunitionManager* tc = new AmmunitionManager(5,10);
tc->FillAmmoArray(10,10);
return 0;
}
The problem is that you initialize AmmunitionManager with the default constructor:
AmmunitionManager *var = new AmmunitionManager();
In you default constructor you do nothing so ammoArray may contain any value.
It is better to initialize all the data to their default values:
AmmunitionManager::AmmunitionManager() : Ammo(), ammoArray(NULL/* or nullptr for C++11 */)
{
}
Now if you call for
var->FillAmmoArray(amVar.getSDamage(),amVar.getBDamage());
It will exit immediately since ammoArray is NULL.
Or probably you want to initialize ammoArray anyway, so the default constructor should have its initialization as well:
AmmunitionManager::AmmunitionManager() : Ammo()
{
ammoArray = new int* [10];
}
Also srand should be called only once, so better to place this code
srand(time(NULL));
in the main() or any other module which is guaranteed to be executed only once.
In the destructor, there is no need to zero *ammoArray=0, it actually puts 0 at the first element of that array (and that's it), you anyway delete it. And imagine that ammoArray is NULL, accessing *ammoArray would cause another segmentation fault.
Also there is no need to check for ammoArray beibg NULL before deleting it. The standard allows to 'delete' NULL pointers. delete will just return without doing nothing.
General note
It is better to use (safer and easier to maintain) std::vector instead of (dynamic) arrays and smart pointers instead of flat ones.
It's a bit tricky answering without building and debugging, but the first thing that strikes me are: Why are you using pointers (*) to int throughout?
Why don't you just have the array as a pointer:
int *ammoArray;
and make the other int-instances (remove the pointers - * and the address-of's (&))?
Regards
I'm quite new to C++. I've been trying to figure this out for days - there'll be an easy solution no doubt but I haven't been able to find it (after much googling)! My problem is this:
I'm trying to create a class with a member function that reads in characters from a file and stores them in an array. I want to be able to create multiple objects (not sure how many - decided by the user), each with their own arrays filled with characters taken from different files. I think I've managed to do that. How would I then go about accessing the object's array in main?
The code I'm working on is long and messy but something along these lines (char.txt contains simply '12345' in this case):
#include <iostream>
#include <fstream>
using namespace std;
class Something{
public:
void fill_array(char array_to_fill[]){
char next;
ifstream input;
input.open("chars.txt");
input.get(next);
while(!input.eof())
{
for(int i = 0; i < 6; i++)
{
array_to_fill[i] = next;
input.get(next);
}
}
}
};
int main()
{
Something* something = new Something[1];
char array_to_fill[5];
something->fill_array(array_to_fill);
//I'd like to be able to access the array here; for example - to cout the array.
return 0;
}
Apologies if a) my terminology is wrong b) my code is rubbish or c) my question is stupid/doesn't make sense. Also I should add I haven't learnt vectors yet and I'm not supposed to use them for the program I'm making. Any help would be much appreciated. Cheers!
Your class does not store the array at all. It is simply a holder for a method. You probably want something like this, where each instance of the class holds the array. (I changed it to std::string since they are nicer to work with.)
class Something
{
private:
std::string data;
public:
void fill_data( const std::string& filename )
{
ifstream file( filename );
file >> data;
file.close();
}
std::string get_data() const
{
return data;
}
}
int main()
{
std::vector<Something> my_things;
my_things.push_back( Something() );
my_things[0].fill_data( "chars.txt" );
cout << my_things[0].get_data() << std::endl;
my_things.push_back( Something() );
my_things[1].fill_data( "another_file.txt" );
cout << my_things[1].get_data() << std::endl;
}
Since you are using C++, not C, get used to writing C++ code instead of C. (std::vector instead of C arrays (for unknown length arrays), std::string instead of char*, etc).
I think your question is too general for the format of stack overflow, but what you want in this case is to either create a public member, or create a private member with setters and getters.
class Something
{
public:
std::string m_string;
}
int main()
{
Something A;
A.m_string = "toto";
cout << A.m_string;
return 0;
}
Put a string for convenience (you could use a const char* but you will have to understand what is the scope to know when it will not be accessible anymore and you are not quite there yet) and there may be typos since I typed this from a phone.
If you really want to access the chars themselves, pass a char* with a size_t for the length of the array or use std::array if possible.
Right now the method fill_array is creating a local copy of array_to_fill, so any changes that you make to array_to_fill only happen in the local method. To change this, pass by pointer. This way the pointer gets copied instead of the whole array object. I didn't test this but it should look more like this:
void fill_array(char* array_to_fill){
...
}
You don't need to change anything in the main method.
To actually access the elements you can use [] notation. I.e. cout << array_to_fill[0] in the main method.
Edit: I think that change should work.
I have a class I’d like to be able to set a flag in that says if it is heap allocated so it can properly clean up after itself and not try to delete itself if it’s on the stack. The problem is...I can’t seem to override both new and the constructors at the same time. So it goes from my new overload that sets the isHeapAllocated flag and then into my constructor which resets the flag.
void* String8::operator new(size_t size)
{
String8* string = (String8*)malloc(size);
if(string == null)
Exception("allocation fail : no free memory");
string->isHeapAllocated = true;
return string;
}
String8::String8()
{
isHeapAllocated = false;
}
So new String8() sets the isHeapAllocated flag and then resets it to false. Is there any way to do this?
It will not work as intended:
The new operator return unitialized memory to be given to the constructor.
You -correctly- do String8* string = (String8*)malloc(size);, but *string, at this stage is not yet a String8 object: it is just the memory bulk that will contain it.
So string->isHeapAllocated = true; in fact sets a flag inside a not yet constructed object (that's UB).
Admitting this will not compromise the OS process, so that the program will not crash (you write memory that belongs already to you, after all ...), when you will later do something like String8* ptr = new String8;, after new returns, the String8::String8 constructor is called, and the member will be set back to "false" independently on what you did in the new operator overload.
The idiomatic way to manage C++ objects is let who allocate to be responsible to deallocate.
(and if "who" it is the stack, it just do that by definition).
This is a bad idea, but here’s a way to do it that doesn’t invoke undefined behaviour.
#include <iostream>
#include <memory>
#include <set>
using namespace std;
class C {
public:
void* operator new(size_t size) {
C* c = static_cast<C*>(::operator new(size));
heap_instances.insert(c);
return c;
}
C() : heap_allocated(heap_instances.find(this) != heap_instances.end()) {}
const bool heap_allocated;
private:
static set<const C*> heap_instances;
};
set<const C*> C::heap_instances;
int main(int argc, char** argv) {
cout << boolalpha;
C stack;
cout << stack.heap_allocated << '\n'; // false
C* heap_nozero = new C;
cout << heap_nozero->heap_allocated << '\n'; // true
delete heap_nozero;
C* heap_zero = new C();
cout << heap_zero->heap_allocated << '\n'; // true
delete heap_zero;
}
You can remove pointers from heap_instances when you’re done with them, of course, and use a more suitable container if you’re running in a multithreaded environment. But again, I wouldn’t recommend that you actually do this—deciding behaviour based on allocation is not something an object ought to do.
The only legitimate reason I can think of for this is to enable delete this. While that’s safe if you’re careful not to access members after the object’s suicide, it’s usually saner to let objects manage the lifetimes of other objects.
Note that the construtor gets called if it is allocated on the stack or the heap and there is no way for the object to detect if it was allocated on the stack or in the heap.
To create an object at the stack you don't use any memory allocation functions like this
String8 myString;
To create it on the heap you do
String8 *myString = new String8();
note that you do have to do the cleanup manually after not using the object anymore.
For the use of Heap objects bound to stack scope you can check out the RAII principle which is used intensly by c++ programs (see here for a better explaination of the difference of heap allocation and stack allocation).
Not sure why you need this, really. It's caller's responsibility to call delete if needed and your class's destructor should not be different whether it's called on the object on stack or on the heap... But, maybe, you are doing some special purpose class... Here is my quick take on it.
EDIT: You should also, probably, add custom delete operator to your class, unless you know that global delete calls a deallocation function that matches the allocation function you use in your custom new operator.
#include <cstdlib>
#include <iostream>
namespace so
{
class _test_
{
private:
static bool flag_allocation_heap;
bool flag_heap;
public:
_test_()
: flag_heap( flag_allocation_heap )
{
flag_allocation_heap = 0;
std::cout << flag_heap << std::endl;
}
void * operator new( std::size_t _size )
{
_test_ * test_ = static_cast< _test_ * >( std::malloc( _size ) );
flag_allocation_heap = 1;
return ( test_ );
}
};
bool _test_::flag_allocation_heap = 0;
} // namespace so
int main()
{
so::_test_ test_stack_;
so::_test_ * test_memory_ = new so::_test_;
delete test_memory_;
return( 0 );
}
Output:
0
1
Using malloc and free, it is easy to allocate structures with extra data beyond the end. But how do I accomplish the same with new/ delete?
I know I could use placement new syntax along with malloc for the allocation part, but will delete work properly and portably if I place an object in memory allocated by malloc?
What I want to accomplish is the same as the following example, but using new/ delete instead of malloc/ free, so that constructors/destructors will be called properly:
#include <cstdlib>
#include <cstring>
#include <iostream>
class Hamburger {
int tastyness;
public:
char *GetMeat();
};
char *Hamburger::GetMeat() {
return reinterpret_cast<char *>(this) + sizeof(Hamburger);
}
int main(int argc, char* argv[])
{
Hamburger* hb;
// Allocate a Hamburger with 4 extra bytes to store a string.
hb = reinterpret_cast<Hamburger*>(malloc(sizeof(Hamburger) + 4));
strcpy(hb->GetMeat(), "yum");
std::cout << "hamburger is " << hb->GetMeat() << std::endl;
free(hb);
}
Output: hamburger is yum
You can do this without resorting to malloc/free or undefined behavior (I'm not sure about the reinterpret_cast, but at least construction/destruction can be done just fine).
To allocate the memory you can just call the global operator new directly. After that you use good old placement new to construct the object there. You have to guard the ctor-call though, since the "placement delete" function that's called if the ctor fails will not release any memory but just do nothing (just as placement new does nothing).
To destroy the object afterwards you can (and may) call the destructor directly, and to release the memory you can call the global operator delete.
I think it should also be OK to just delete it as you would any normal object, since calling the destructor and global operator delete afterwards is just what the normal delete will do, but I'm not 100% sure.
Your example modified like that:
#include <cstdlib>
#include <cstring>
#include <iostream>
class Hamburger {
int tastyness;
public:
char *GetMeat();
};
char *Hamburger::GetMeat() {
return reinterpret_cast<char *>(this) + sizeof(Hamburger);
}
int main(int argc, char* argv[])
{
Hamburger* hb;
// Allocate space for a Hamburger with 4 extra bytes to store a string.
void* space = operator new(sizeof(Hamburger) + 4);
// Construct the burger in that space
hb = new (space) Hamburger; // TODO: guard ctor call (release memory if ctor fails)
strcpy(hb->GetMeat(), "yum"); // OK to call member function on burger now
std::cout << "hamburger is " << hb->GetMeat() << std::endl;
// To delete we have to do 2 things
// 1) call the destructor
hb->~Hamburger();
// 2) deallocate the space
operator delete(hb);
}
If I were you, I'd use placement new and an explicit destructor call instead of delete.
template< typename D, typename T >
D *get_aux_storage( T *x ) {
return reinterpret_cast< D * >( x + 1 );
}
int main() {
char const *hamburger_identity = "yum";
void *hamburger_room = malloc( sizeof( Hamburger )
+ strlen( hamburger_identity ) + 1 );
Hamburger *hamburger = new( hamburger_room ) Hamburger;
strcpy( get_aux_storage< char >( hamburger ), hamburger_identity );
cout << get_aux_storage< char const >( hamburger ) << '\n';
hamburger->~Hamburger(); // explicit destructor call
free( hamburger_room );
}
Of course, this kind of optimization should only be done after profiling has proven the need. (Will you really save memory this way? Will this make debugging harder?)
There might not be a significant technical difference, but to me new and delete signal that an object is being created and destroyed, even if the object is just a character. When you allocate an array of characters as a generic "block," it uses the array allocator (specially suited to arrays) and notionally constructs characters in it. Then you must use placement new to construct a new object on top of those characters, which is essentially object aliasing or double construction, followed by double destruction when you want to delete everything.
It's better to sidestep the C++ object model with malloc/free than to twist it to avoid dealing with data as objects.
Oh, an alternative is to use a custom operator new, but it can be a can of worms so I do not recommend it.
struct Hamburger {
int tastyness;
public:
char *GetMeat();
static void *operator new( size_t size_of_bread, size_t size_of_meat )
{ return malloc( size_of_bread + size_of_meat ); }
static void operator delete( void *ptr )
{ free( ptr ); }
};
int main() {
char const *hamburger_identity = "yum";
size_t meat_size = strlen( hamburger_identity ) + 1;
Hamburger *hamburger = new( meat_size ) Hamburger;
strcpy( hamburger->GetMeat(), hamburger_identity );
cout << hamburger->GetMeat() << '\n';
}
Urgh. Well, let's see. You definitely can't allocate with new/malloc and dispose with free/delete. You have to use matching pairs.
I suppose you could use "hp = new char[sizeof(Hamburger) + 4]" and "delete[]((char *) hp)", along with explicit constructor/destructor calls, if you really wanted to do this.
The only reason I can think why you'd want to do this would be you didn't have the Hamburger source -- i.e., it was a library class. Otherwise you'd just add a member to it! Can you explain why you'd want to use this idea?
There is another way that you could approach this if you have a reasonably constrained set of padding amounts. You could make a template class with the padding amount as the template parameter and then instantiate it with the set of possible padding amounts. So if, for example, you knew that you were only going to need padding of 16, 32, or 64 bytes, you could do it like this:
template <int Pad>
class Hamburger {
int tastiness;
char padding[Pad];
};
template class Hamburger<16>;
template class Hamburger<32>;
template class Hamburger<64>;
Is there any reason why the straightforward, easy and safe way is not applicable?
class Hamburger {
public:
void Extend( const std::string& pExtension) {
mContent += pExtension;
}
const std::string& GetMeat() ...
private:
std::string mContent;
};
int main() {
Hamburger hb;
hb.Extend("yum");
std::cout << "hamburger is " << hb.GetMeat() << std::endl;
}