Nullpointer error in exercise - c++

My experience so far is mostly in Java but i'm trying to learn C++ and i'm still struggling to understand pointers, overloads etc. Forgive me about the title but i didn't know how to present my problem. Anyway i came across this exercise while studying and i would like some help. The exercise provides a class Container and a main() and i'm supposed to extend the Class and make the main() work to provide the proper result.
template <typename T>
class Container
{
protected:
T * storage;
size_t num_items;
size_t storage_size;
public:
virtual void operator += (const T item) { }
virtual ~Container() { }
Container() : storage(nullptr), num_items(0), storage_size(0) { }
T operator [] (size_t index)
{
if (num_items==0)
return T(0);
return storage[index<num_items?index:num_items];
}
inline size_t size() { return num_items; }
};
void main(int argc, char* argv[])
{
Container<long> * store = new Container_ex(); // I'm suppose to fill this gap
---------------
size_t num_data;
cin >> num_data;
for (size_t i=0; i<num_data; i++)
{
long item;
cin >> item;
*store+=item;
}
for (size_t i=0; i<store->size(); i++)
std::cout << (*store)[i] << " ";
std::cout << std::endl;
delete store;
}
So far i've done this. The problem lies when i try to overload += cause i get an exception error (this->storage was nullptr) but in any case i don't understand the use of storage completely in this exercise so i would appreciate any help.
class Container_ex : public Container<long> {
public:
Container_ex() : Container() {}
~Container_ex() { delete[] storage; }
void operator += (const long item)
{
*storage = const_cast<long&>(item);
*storage = *storage + item;
num_items = num_items + 1;
storage_size = storage_size + 1;
}
};

Your pointer needs to point on a valid memory address before you can do anything with it. If it doesn't, it leads to undefined behavior that can end in a crash of your application, for example.
But when do you need to do it ? Certainly not in the operator overload. When you create an object, you must ensure that it is in a valid state. It means either setting it to nullptr so it is a null pointer, or allocating memory for it.
If you do it in operator overload, how can you be sure that operator overloading will be used ? Maybe the user just wants doing []. So you have to make a constructor allocating memory for your pointer. Or, better, use smart pointers that will save your life and provent headaches, especially if you come from a language where there is no explicit pointer like Java.
Finally, there are some great books to learn C++ better than the course you use.
Programming: Principles and Practice Using C++ by Bjarne Stroustrup, the creator of C++. Assume no previous experience in programming. Check to take the updated version for C++11 | C++14.
C++ Primer by Stanley Lippman, Josée Lajoie and Barbara E. Moo. ~1k pages, full of details and explanations on C++11. Good for beginners with a previous experience in programming.

Related

how to find and track objects and functions that using a dynamically allocated memory?

if we have a code like this :
void g(int *n){
int m=n[1];
n= null ;
}
void main(){
int ∗ p = (int∗)malloc(10 ∗ sizeof (int));
int * q= p;
g(p);
}
so we know if we overload malloc, calloc , realloc ,new ,free and delete functions we can track first pointer that create or delete with this functions(p pointer in above example ) but how can i find and track other pointers and functions that using this allocated memory ? ( q pointer and g function in above example ) .should i overload Assignment statement and function call ? if yes how ? in other words i want to know live objects and last used time and location of an allocated memory too .
i want to implement an custom memory leak detection tools so i need to find all objects and pointer that using an allocated memory before report it that's leak or not .
What you're talking about is called reference counting. Searching stackoverflow for this topic gives you these results:
What is a smart pointer and when should I use one?
How does a reference-counting smart pointer's reference counting work?
what exactly reference counting in c++ means?,
The standard template library already has a std::shared_ptr which does that.
We need to keep track of the lifecycle of the resource, this is possible by controlling the creation, the copying and the deletion. If you do it without using a class, you'll end up with some functions, a state variable and a global variable. This is not very effective in keeping the concept of the shared resource in the focus of the user's mind. One tends to forget that one is using a shared resource because one sees a naked pointer and tends to use it like one, which would disregard the provided shared-pointer functionality.
If you were to encapsulate the functionality in a class, you should want to implement the concept for all types i.e. you should want to use templates. one way would be this:
#include <vector>
#include <stdexcept>
#include <cstdlib>
#ifndef SHARED_PTR_H
#define SHARED_PTR_H
template<class Tres_t>
class shared_pointer
{
// members
Tres_t* data_;
static std::vector<std::size_t> ref_counts_;
std::size_t ref_index_ = {};
public:
// lifecycle
shared_pointer() = delete;
shared_pointer(const std::size_t& size)
: data_{nullptr}
{
data_ = static_cast<Tres_t*>(std::malloc(size * sizeof(Tres_t)));
ref_counts_.push_back(1);
ref_index_ = ref_counts_.size() - 1;
}
shared_pointer(const shared_pointer& rhs)
: data_{rhs.data_}, ref_index_{rhs.ref_index_}
{
if (ref_index_ >= ref_counts_.size())
{
throw std::runtime_error("shared_pointer_ctor_index_error");
}
++ref_counts_[ref_index_];
}
shared_pointer(shared_pointer&& rhs)
: data_{rhs.data_}, ref_index_{rhs.ref_index_} {}
shared_pointer& operator=(const shared_pointer& rhs)
{
data_ = rhs.data_;
ref_index_ = rhs.ref_index_;
if (ref_index_ >= ref_counts_.size())
{
throw std::runtime_error("shared_pointer_ctor_index_error");
}
++ref_counts_[ref_index_];
}
shared_pointer& operator=(shared_pointer&& rhs)
{
data_ = rhs.data_;
ref_index_ = rhs.ref_index_;
}
~shared_pointer()
{
if (ref_counts_[ref_index_] == 0)
{
std::logic_error("shared_point_dtor_reference_counting_error");
}
--ref_counts_[ref_index_];
if (ref_counts_[ref_index_] == 0)
{
std::free(data_);
}
}
// main functionality
Tres_t* data()
{
return data_;
}
const Tres_t* data() const
{
return data_;
}
};
template<class Tres_t>
std::vector<std::size_t> shared_pointer<Tres_t>::ref_counts_ = {};
#endif
I've tested this code only rudimentarily so I'll leave it to you to test and improve it.

Dynamically Allocated Memory Constructor

I'm trying to create a constructor in which the strings are dynamically allocated. I've looked up dynamically allocated memory several times and watched a video about it, but I'm still not 100% sure if I'm understanding the concept. I'm hoping an example specific to what I'm coding will help me out a bit.
These are the private variables I have in my h file:
string* tableID;
int numSeats;
string* serverName;
With that in mind, could someone tell me how I could dynamically allocate memory for the strings in this constructor?
Table::Table(const string& tableID, int numSeats, const string& serverName) {
}
Finally, I would greatly appreciate it if someone could tell me the purpose of dynamically allocated memory. I've see explanations on what dynamically allocate memory is, but I'm not understanding the use of it. Why use dynamically allocated memory? What are the benefits? What are the drawbacks? Thank you!
EDIT: I'm including the rest of the h file. Note that this wasn't created by me, so I can't make changes to it. I can only adhere to it in the cpp file.
#include <string>
#include "party.h"
using std::string;
class Table {
public:
Table();
Table(const string& tableID, int numSeats, const string& serverName);
~Table();
const string* getTableID() const { return tableID; }
int getNumSeats() const { return numSeats; }
const string* getServerName() const { return serverName; }
void decrementTimer() { timer--; }
int getTimer() const { return timer; }
void setTimer(int duration) { timer = duration; }
const Party* getParty() { return party; }
void seatParty(const Party* newParty);
void clearTable() { party = nullptr; timer = 0; }
private:
string* tableID;
int numSeats;
string* serverName;
int timer;
const Party* party;
};
The easiest way to get what you want is to take advantage of the Member Initializer List as this also solves the problem of having the parameters shadow the member variables of the same name.
Table::Table(const string& tableID,
int numSeats,
const string& serverName):
tableID(new string(tableID)),
numSeats(numSeats),
serverName(new string(serverName))
{
}
Allocation is performed with the new operator. Later you will have to release the dynamically allocated memory with the delete operator. Here is documentation on new and the same for delete.
But the use a pointer requirement is bizarre as storing pointers to string makes everything else you with the class do orders of magnitude more difficult. This may be the point of the assignment, but there are better and less-confusing ways to teach this lesson.
The allocated strings must be released. The C++ idiom of Resource Allocation Is Initialization (What is meant by Resource Acquisition is Initialization (RAII)?) suggests you have a destructor to automate clean-up to ensure that it is done. If you need a destructor, you almost always need the other two members of The Big Three (What is The Rule of Three?) and possibly need to take The Rule of Five into account as well.
Whereas because string observes the Rule of Five for you, you should be able to take advantage of the Rule of Zero and implement no special functions.
M.M raises an excellent point in the comments. The above example is too naive. It is probably all you need for the assignment, but it's not good enough for real code. Sooner or later it will fail. Example of how it fails.
First we replace string with something that can expose the error:
class throwsecond
{
static int count;
public:
throwsecond(const string &)
{
if (count ++)
{
count = 0; // reset count so only every second fails
throw runtime_error("Kaboom!");
}
cout << "Constructed\n";
}
~throwsecond()
{
cout << "Destructed\n";
}
};
int throwsecond::count = 0;
Then a simple class that does basically the above with less frills
class bad_example
{
throwsecond * a;
throwsecond * b;
public:
bad_example(): a(nullptr), b(nullptr)
{
}
bad_example (const string& a,
const string& b)
{
this->a = new throwsecond(a);
this->b = new throwsecond(b);
}
~bad_example()
{
delete a;
delete b;
}
};
and a main to exercise it
int main()
{
cout << "Bad example\n";
try
{
bad_example("", "");
}
catch (...)
{
cout << "Caught exception\n";
}
}
Output:
Bad example
Constructed
Caught exception
We have an object constructed and never destroyed.
Since a default constructor has been defined by Table we can, with a compiler that supports the C++11 or a more recent Standard, take advantage of delegated constructors to force destruction of the partially constructed object because it has been fully constructed by the default constructor.
class good_example
{
throwsecond * a;
throwsecond * b;
public:
good_example():
a(nullptr), b(nullptr) //must be nulled or destruction is dicey
{
}
good_example (const string& a,
const string& b) : good_example() // call default constructor
{
this->a = new throwsecond(a);
this->b = new throwsecond(b);
}
~good_example()
{
delete a;
delete b;
}
};
Output:
Good example
Constructed
Destructed
Caught exception
One construct and one destruct. The beauty of this approach is it scales well and adds nothing to the code that you don't already have. The cost is minimal, a and b get initialized and then assigned as opposed to just initialization. Faster code is useless if it doesn't work.
Full example: https://ideone.com/0ckSge
If you can't compile to a modern standard, you wind up doing something like
the next snippet to make sure everything is deleted. It's main sin is it's ugly, but as you add more classes that must be constructed and destroyed it starts getting unwieldy.
Table::Table(const string& tableID,
int numSeats,
const string& serverName):
tableID(NULL),
numSeats(numSeats),
serverName(NULL)
{
try
{
this->tableID(new string(tableID)),
// see all the this->es? don't shadow variables and you won't have this problem
// miss a this-> and you'll have a really bad day of debugging
this->serverName(new string(serverName))
// more here as required
}
catch (...)
{
delete this->tableID;
delete this->serverName;
// more here as required
throw;
}
}
There is probably a way to improve on this and make it more manageable, but I don't know it. I just use newer standards and value semantics (I'd love it if someone can provide a good link that describes this concept) where possible.

Problems with default value of pointer to pointer in constructor

When we are using a "double" pointer to class, what are we writing in the constructor with arguments? Are we using one pointer for the allocated memory ?
Here is the code. It doesn't compile and I don't understand why. Thanks for the help.
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
class Article{
private:
char title[100];
char author[50];
char *content;
bool publish;
public:
Article(char *title="", char *author="", char *content="", bool publish=0){
strcpy(this->title, title);
strcpy(this->author, author);
this->content=new char[strlen(content)+1];
strcpy(this->content, content);
this->publish=publish;
}
void show(){
cout<<title<<endl;
cout<<author<<endl;
cout<<content<endl;
}
~Article(){
delete [] content;
}
};
class Newspaper{
private:
char name[100];
Article **p;
int articles;
Article first;
public:
Newspaper(char *name="", Article **p=Article(), int articles=0, Article first=Article()){
strcpy(this->name, name);
}
};
int main() {
char title[100], author[50], content[100];
int n;
cin >> n;
char name[100];
cin.getline(name, 100);
cin.getline(name, 100);
Article first("VAZNO","OOP","Vezba:OOP",true);
Newspaper v(name,first);
Article **s = new Article*[n];
for(int i = 0; i < n; ++i) {
cin.getline(title, 100);
cin.getline(author, 50);
cin.getline(content, 100);
v.addArticle(Article(title, author, content, true)); //se koristi copy konstruktor
}
v.showFirst();
v.showLongest();
cout << v.totalofauthor(author) << endl;
for(int i = 0; i < n; ++i) {
delete s[i];
}
delete [] s;
return 0;
}
Solution to your question:
From your code it seems that a Newspaper uses a pointer to a pointer (what you call a double pointer) for keeping track of the Articles:
Newspaper(char *name, Article **p , // This would be ok
int articles = 0, Article first = Article())
but that you've trouble to define a default argument for it:
Newspaper(char *name="", Article **p=Article(), // oops doesn't compile
int articles = 0, Article first = Article())
The reason is that a "double" pointer is not the same as the object itself. If you want a default argument here, you must provide a double pointer as well.
This code does exactly this:
Newspaper(char *name = "", Article **p = new Article*, // this is ok !
int articles = 0, Article first = Article()){
So this is the solution to your question.
But what's your problem ?
But what's the purpose or providing a dummy pointer, pointing to nowhere as default argument ?
Later you try to create a Newspaper based on an article again:
Newspaper v(name, first); // won't work, because first is not a pointer either
So the problem is not the constructor, but the whole principle. It seems that you really want to create a Newspaper based on an Article, and that you use defaults to cover the case where someone wants to create a Newspaper without Article.
Apparently your design also foresees that Articles may be added dynamically:
v.addArticle(Article(title, author, content, true));
Finally it seems that you really have a problem with pointers: when in the constructor you write, you didn't initialise the poitner to a memory region large enough to hold the name:
Newspaper(char *name = "", ...) {
strcpy(this->name, name); // Ouch !! pointer name is not initalized !
}
So once you'll get your code compiled, your programme won't work ! As this->name is a pointner that is never initialized, your strcpy() will cause memory corruption and undefined behaviour (crash!?).
Recommendations
First, get a book or a tutorial to understand and master pointers. If you do'nt you'll quickly be completely lost in your C++ class.
In the meantime, get rid of your char* and strcpy() and alike, and use std::string instead.
Last, consider the use of std::vector to manage the dynamic Article container. A dynamic array of poitners implemented with Article** would need extra logic, such as maintaining the size, reallocation of memory once the number of article grows, not speaking of the ownership (allocation/deallocation) of the Articles you put in the array.
Based on these recommendations, your Newspaper would look like this:
class Newspaper{
private:
string name;
vector<Article> p; // p.size() will provide the number of articles
public:
Newspaper(string name = "") : name(name) { } // empty newspaper
Newspaper(string name, Article& a) : Newspaper(name) { // combo
addArticle(a);
}
void addArticle(Article &a) {
p.push_back(a); // add and article to the vector
}
... // rest of the code, here
};
And here a little more

Array Wrapper class in C++

So, I'm new to C++ (brand new), and as an assignment I have to write a class that acts as an array wrapper. Since I'm so new, I'm unsure whether my overloaded operators and such work, so if anyone could be so kind as to tell me how my code looks:
This would be the header:
class MyArray
{
private:
string* sList;
unsigned int size;
public:
MyArray(const unsigned int size = 1);
MyArray(const MyArray &toCopy);
MyArray& operator=(const MyArray& toAssign);
~MyArray();
//MyArray& operator+
string& operator[](const int index);
const int size();
};
And this would be the underlying code:
MyArray::MyArray(const unsigned int initSize)
: size(initSize)
{
sList = new string[initSize];
return;
}
MyArray::MyArray(const MyArray &toCopy)
: size(toCopy.size)
{
if(toCopy.sList)
{
sList = new string[size];
for(int a=0; a<size; a++){
strcpy(sList[a], toCopy.sList[a]);
}
}
else sList = NULL;
return;
}
MyArray& operator=(const MyArray& toAssign)
{
if(this != &toAssign)
{
if(sList)
{
delete [] sList;
}
size = toAssign.size;
if (toAssign.sList)
{
sList = new string[size];
for(int a=0; a<size; a++){
strcpy(sList[a], toCopy.sList[a]);
}
}
else
{
sList = NULL
}
}
}
MyArray::~MyArray()
{
delete [] sList;
return;
}
string& MyArray::operator[](const int index)
{
return sList[index];
}
const int MyArray::size()
{
return this.size;
}
The operator+ function still needs to be written, but I want to make sure what I have makes sense before I proceed.
How do you want your code (i.e. the class you are authoring) to be used by other programmers (including you)?
Write an example program to demonstrate the use of your class.
An example program serves as a rudimentary test set. You can start as the following.
int main() {
MyArray arr1( 5 );
MyArray arr2( arr1 );
}
Have you thought about how user code will put (string?) elements into the MyArray class?
There are couple of other issues with the current version of the code. That is okay to begin with, but it is important for you to learn to test your own code; you need to learn the skill where you have some basic confidence in your own code (not necessarily perfect code) because you cannot always ask somebody else to test your code.
Suggestion: Since you mentioned that you are new, I would suggest you to build a array wrapper class for int's first. This is because, managing strings has some extra challenges than managing ints :-). Once you do that, you can easily do it for strings.
There is a naming conflict between size and size()
Copy C++ strings using =, not strcpy (which is for char*)
Missing MyArray:: in definition of operator=
toCopy should be toAssign in operator=
Missing semicolon after sList = NULL
Missing return *this; at the end of operator=
In defintion of size(), this.size should be size, this->size or (*this).size
All of these mistakes will be discovered by a compiler (you may need to enable warnings for the missing return to be reported; on g++ use the -Wall flag). It is just a matter of understanding the compiler's error messages and knowing how to fix the problems.

Handling Huge Multidimensional Arrays in C++

I'm designing a game in C++ similar to Minecraft that holds an enormous amount of terrain data in memory. In general, I want to store an array in memory that is [5][4][5][50][50][50]. This isn't bad since it amounts to about 100mb of virtual memory since my structure will only be about 8 bytes.
However, I'm having trouble figuring out the best way to handle this. I do want this to be in virtual memory, but obviously not on the stack. And I keep making the mistake some how of creating this array on the stack an causing a stack overflow. What I would like to do is below. This is just code that I threw together to give you an example of what I'm doing, I have code with correct syntax on my machine, I just didn't want to clutter the post.
typedef struct modelBlock
{
// Information about the blocks
} BLOCK;
typedef struct modelGrid
{
bool empty;
BLOCK blocksArray[50][50][50];
} GRID;
class Parent
{
Child* child;
Parent(void);
}
Parent::Parent()
{
Child c;
child = &c;
}
class Child
{
GRID grids[5][4][5];
}
However, every time I do this, I cause a stack overflow (appropriate web site choice right?). I played with using pointer based arrays, but I had a lot of trouble with data being lost outside of its scope.
If anyone could give me some insight on how to get my data to store on the heap instead of the stack, or if I should use some other way of creating my array, I'd really appreciate the help. I'd like to avoid using vectors because of overhead, though I'm not sure how substantial it is.
Use boost::multi_array
If you want to allocate something on the heap, use new.
#include <memory>
class Parent
{
std::auto_ptr<Child> child; // use auto_ptr for dynamically-allocated members
Parent(const Parent&); // You probably don't want to copy this giant thing
public:
Parent();
};
Parent::Parent()
: child(new Child) // initialize members with an initializer list
{
}
Also, avoid mixing C and C++ styles. There's no reason to do
typedef struct blah{ ... } BLAH;
in C++. A struct is just a class with all of the members public by default; just like a class, you can refer to the struct type's name without using the struct tag. There's also no need to specify void for a function that takes no parameters.
boost::multi_array (linked in PigBen's answer) is a good choice over raw arrays.
If you want the class created on the heap, create it with new:
Child * c = new Child;
and then of course delete it, or better still use a smart pointer.
In order to do exactly what you're trying to do you have to declare everything as pointers (and pointers to pointers to pointers to pointers) and then allocate each one individually.
Teh sux!
A better option is to simply allocate the ginormous block in one chunk and use multiple variable along with pointer arithmetic to arrive at the correct location.
Edit: Wasn't paying attention and didn't notice your constructor. That's not only not the way to get your Child allocated on the free-store, it's a great way to create situations eliciting undefined behavior. Your Child will be gone when the constructor is through and the pointer to it will then be invalid. I wonder if you shouldn't run through some basic tutorials before trying to write a game.
Here's something that works and can be built upon without the boost dependency. One downside is it removes use of [][][] style of referencing elements, but it's a small cost and can be added.
template<class T>
class Matrix {
unsigned char* _data;
const size_t _depth;
const size_t _cols;
const size_t _rows;
public:
Matrix(const size_t& depth, const size_t& rows, const size_t& cols):
_depth(depth),
_rows(rows),
_cols(cols) {
_data = new unsigned char [depth * rows * cols * sizeof(T)];
}
~Matrix() {
delete[] _data;
}
T& at(const size_t& depthIndex, const size_t& rowIndex, const size_t& colIndex) const {
return *reinterpret_cast<T*>(_data + ((((depthIndex * _cols + colIndex) * _rows) + rowIndex) * sizeof(T)));
}
const size_t& getDepth() const {
return _depth;
}
const size_t& getRows() const {
return _rows;
}
const size_t& getCols() const {
return _cols;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Matrix<int> block(50, 50, 50);
size_t d, r, c;
for (d = 0; d < block.getDepth(); d++) {
for (r = 0; r < block.getRows(); r++) {
for (c = 0; c < block.getCols(); c++) {
block.at(d, r, c) = d * 10000000 + r * 10000 + c;
}
}
}
for (d = 0; d < block.getDepth(); d++) {
for (r = 0; r < block.getRows(); r++) {
for (c = 0; c < block.getCols(); c++) {
assert(block.at(d, r, c) == d * 10000000 + r * 10000 + c);
}
}
}
return 0;
}
A smaller example (with changed names for all the structs, to make the general principle clearer). The 'Bloe' struct is the one you want to allocate on the heap, and this is accomplished using 'new'.
struct Bla {
int arr[4][4];
};
struct Bloe {
Bla bla[2][2];
};
int main()
{
Bloe* bloe = new Bloe();
bloe->bla[1][1].arr[1][1] = 1;
return 0;
}
I did this by putting all the data in a binary file. I calculated the offset of the data and used seek() and read() to get the data when needed. The open() call is very slow so you should leave the file open during the lifetime of the program.
Below is how I understood what you showed you were trying to do in your example. I tried to keep it straightforward. Each Array of [50][50][50] is allocated in one memory chunk on the heap, and only allocated when used. There is also an exemple of access code. No fancy boost or anything special, just basic C++.
#include <iostream>
class Block
{
public:
// Information about the blocks
int data;
};
class Grid
{
public:
bool empty;
Block (*blocks)[50][50];
Grid() : empty(true) {
}
void makeRoom(){
this->blocks = new Block[50][50][50];
this->empty = false;
}
~Grid(){
if (!this->empty){
delete [] this->blocks;
}
}
};
class Parent
{
public:
Grid (* child)[4][5];
Parent()
{
this->child = new Grid[5][4][5];
}
~Parent()
{
delete [] this->child;
}
};
main(){
Parent p;
p.child[0][0][0].makeRoom();
if (!p.child[0][0][0].empty){
Block (* grid)[50][50] = p.child[0][0][0].blocks;
grid[49][49][49].data = 17;
}
std::cout << "item = "
<< p.child[0][0][0].blocks[49][49][49].data
<< std::endl;
}
This could still be more simple and straightfoward and just use one bug array of [50][50][50][5][4][5] blocks in one memory chunk on the heap, but I'll let you figure out how if this is what you want.
Also, usind dynamic allocation in class Parent only has the sole purpose to use heap instaed of stack, but for such a small array (5*4*5 pointers), allocating it on stack should not be a problem, hence it could be written.
class Parent
{
public:
Grid child[5][4][5];
};
without changing anything in the way it is used.