This has been destroying me for a while. I’m sure there’s a reason for this:
chain operator+(chain c)
{
chain<Object> result;
for (int i = 0; i < length(); i++)
{
result.insert(*(Object*)(memory+(i*sizeof(Object))));
}
for (int i = 0; i < c.length(); i++)
{
result.insert(c[i]);
}
for (int i = 0; i < result.length(); i++) // This for loop successfully shows all objects in result
{
cout << result[i];
}
return result;
}
When the value is returned, ie:
chain<int> a;
cin >> a; // enter "5 6 7 8"
chain<int> b;
cin >> b; // enter "9 10 11 12"
chain <int> c = a+b;
cout << c; // Returns "0 0 7 8 9 10 11 12"
The first two numbers are always 0. I can’t figure out why. This only happens when adding two chains together; if I cout a or b, I get all of the values.
I would really appreciate it if anyone has any info to share 🙂
EDIT**
Full Source
#ifndef CHAIN_H
#define CHAIN_H
#include <iostream>
#include <stdlib.h>
using namespace std;
template <class Object>
class chain
{
public:
chain(){
memorySize = 8;
memory = calloc(memorySize, sizeof(Object));
count = 0;
}
chain(Object item){
memorySize = 8;
memory = calloc(memorySize, sizeof(Object));
count = 0;
insert(item);
}
chain(chain & original){
memorySize = 8;
memory = calloc(memorySize, sizeof(Object));
count = 0;
for (int i = 0; i < original.length(); i++)
{
insert(original[i]);
}
}
~chain(){
free(memory);
}
chain operator+(chain c){
chain<Object> result;
for (int i = 0; i < length(); i++)
{
result.insert(this->operator[](i));
}
for (int i = 0; i < c.length(); i++)
{
result.insert(c[i]);
}
for (int i = 0; i < result.length(); i++)
{
cout << result[i];
}
return result;
}
Object & operator[](int pos){
return *(Object*)(memory+(pos*sizeof(Object)));
}
int length(){
return count;
}
void insert(Object item){
if (count == memorySize)
{
doubleMemory();
}
this->operator[](count) = item;
count++;
}
private:
int count;
int memorySize;
void * memory;
void doubleMemory(){
memorySize *= 2;
memory = realloc(memory, (memorySize*sizeof(Object)));
}
};
template <class Object>
ostream& operator<<(ostream& out, chain<Object>& c){
for (int i = 0; i < c.length(); i++)
{
out << c[i] << " ";
}
}
template <class Object>
istream& operator>>(istream& in, chain<Object>& c){
char ch;
int number = 0;
int sign;
while(ch != '\n')
{
ch = in.get();
if (ch == '-')
{
sign = 1;
}
else if (ch >= '0' && ch <= '9')
{
number *= 10;
number += (ch-48);
}
else if (ch == ' ' || ch == '\n')
{
number = sign == 1? 0 - number : number;
c.insert(number);
sign = 0;
number = 0;
}
}
}
#endif
Here’s the code I’m testing against:
#include "chain.h"
using namespace std;
int main(){
chain<int> a, b, c;
chain<int> d(10);
chain<int> e(d);
cin >> a;
cout << endl;
cout << endl;
c = a+d;
cout << c;
}
~
The code you’ve shown isn’t the problem. The real problem is probably either in the copy constructor or the destructor of
chain– maybe also in theinsertmethod (or, on C++11, in the move constructor).(It could also be in
Object’s copy constructor but I think that’s unlikely.)EDIT: Oh my. Don’t write such code in C++. It’s unsafe left, right and center. As long as
Objectis a POD you should be fine but if it isn’t this code yields undefined behaviour. In particular, it doesn’t call the proper constructors and destructors for the objects you store in your chain.Furthermore, your copy constructor should take an argument of type
chain const&since you’re not modifying the passedchain. This in turn requires that you make your class const correct by providing an appropriateconstoverload ofoperator [].Finally and most glaringly, you violate the rule of three because you don’t implement
operator =for yourchain. Trying to assign onechainto another will consequently result in double frees.Generally avoid
callocandfreeand use a standard container instead, or, if that’s not an option, usenew[]plus a smart pointer like boost::shared_array to manage memory (but do not usedelete[]).Another thing, never use
using namespacein a header file, it will pollute the namespace and lead to name conflicts in the weirdest places.