Weird crash when destructor of an STL vector is called - c++

I have a program that gets some data from a mysql database, calls a function to process that data, and exits. I'm getting a weird error when running it...the program crashes when the function returns a value. As I suspected it's a problem with the destructor of one of my classes. The class holds two vectors (one of doubles, the other of a date class I wrote myself). The program crashes when the vector of doubles is destroyed.
Manually erasing the vector in the destructor doesn't do anything.
When I call the destructor manually I don't get this error. It only happens when I return a value from my function. Going line-by-line the crash happens in stl_vector.h on the line
{ _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); }
Googling hasn't been very helpful...I found that assigning a value outside the size of the vector might trigger something like this but I've gone through my code and ensured that that doesn't happen.
The error:
Program received signal SIGTRAP, Trace/breakpoint trap.
In ntdll!DbgUiConnectToDbg () (C:\WINDOWS\system32\ntdll.dll)
The call stack:
#0 7C90120F ntdll!DbgUiConnectToDbg() (C:\WINDOWS\system32\ntdll.dll:??)
#1 7C96EE31 ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#2 7C96F26E ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#3 7C970456 ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#4 7C94BAFC ntdll!LdrFindEntryForAddress() (C:\WINDOWS\system32\ntdll.dll:??)
#5 00000000 0x006b0000 in ??() (??:??)
#6 00000000 0x50000061 in ??() (??:??)
#7 00000000 0x00f57008 in ??() (??:??)
#8 00000000 0x006b0000 in ??() (??:??)
#9 00000000 0x00f57008 in ??() (??:??)
#10 00000000 0x40000060 in ??() (??:??)
#11 00000000 0x00f60558 in ??() (??:??)
#12 00000000 0x002240b0 in ??() (??:??)
#13 00000000 0x00223804 in ??() (??:??)
#14 7C96F2D7 ntdll!RtlpNtMakeTemporaryKey() (C:\WINDOWS\system32\ntdll.dll:??)
#15 7C91A1BA ntdll!RtlpUnWaitCriticalSection() (C:\WINDOWS\system32\ntdll.dll:??)
#16 77C2C2DE msvcrt!free() (C:\WINDOWS\system32\msvcrt.dll:??)
#17 00000000 0x006b0000 in ??() (??:??)
#18 00000000 0x00000000 in ??() (??:??)
Using MinGW in Code::Blocks on winxp. There's a ton of code and since I don't really know where it goes wrong I don't know what to include here...
Thanks for the help.
Edit:
A bunch of code that may or may not be relevant:
Fetching the data, initializing the dated_observations objects (the vectors in these are causing the crashes) and adding the data to them (note that from this point up until the function terminates, I only read values from these objects...no elements are added, modified, or deleted):
query_ss << "SELECT * FROM stock_data WHERE stock_id = " << stock1_id;
mysql_query(connect,query_ss.str().c_str());
query_ss.str("");
res_set = mysql_store_result(connect);
numrows = mysql_num_rows(res_set);
dated_observations s1_p(numrows);
dated_observations s1_r(numrows);
for(i = 0; i < numrows; i++) {
row = mysql_fetch_row(res_set);
s1_p.my_insert(row[2], std::atof(row[3]));
s1_r.my_insert(row[2], std::atof(row[4]));
}
The dated class:
#ifndef _DATED_H_
#define _DATED_H_
#include <vector>
#include "date.h" // my date class
template <class T> class dated {
private:
int counter;
public:
vector<date> dates_;
vector<T> elements_;
//dated<T>();
dated<T>(const int&);
dated<T>(const dated<T>&);
dated<T> operator= (const dated<T>&);
~dated() { clear(); };
void clear(); // erasing
void insert(const date&, const T&); // insert somewhere
void my_insert(const date&, const T&); // insert at the end
bool empty() const ;
int size() const ;
bool contains(const date& d) const ;
date date_at(const int& t) const ; // accessing elements, here dates
T element_at(const int& t) const ; // index directly
T element_at(const date& d) const ; // index indirectly, specify what date
//date last_date() const ;
//T last_element() const;
// next: the element either on date d, if d is here, else the last observation before d.
T current_element_at(const date& d) const ;
vector<T> elements() const; // all elements as vector<T>
vector<date> dates() const; // all dates as vector<date>
date first_date() const; // simple queries
date last_date() const;
T first_element() const;
T last_element() const;
void set_counter(int cnt);
int get_counter() const;
int index_of_date(const date& d) const; // when searching in the data,
int index_of_last_date_before(const date& d) const; // these are useful functions
int index_of_first_date_after(const date& d) const;
int no_observations_between(const date&first, const date& last) const;
void remove(const date&); // removing one or more elements
void remove_between_including_end_points(const date&, const date&);
void remove_between(const date&, const date&);
void remove_before(const date&);
void remove_after(const date&);
};
#include "dated_main.h"
#include "dated_search.h"
#include "dated_remove.h"
template<class T> dated<T> observations_between(const dated<T>& obs,const date&first, const date& last);
template<class T> dated<T> observations_after(const dated<T>& obs, const date& first);
template<class T> dated<T> observations_before(const dated<T>& obs, const date& last);
template<class T> dated<T> end_of_year_observations(const dated<T>&);
template<class T> dated<T> beginning_of_month_observations(const dated<T>&);
template<class T> dated<T> end_of_month_observations(const dated<T>&);
template<class T> dated<T> observations_matching_dates(const dated<T>& obs, const vector<date>& dates);
#include "dated_util.h"
#endif
Some of the methods of the dated class:
//template<class T> dated<T>::dated(){;}; // not necessary to do anything,
template<class T>dated<T>::dated(const int& init_size = 0) {
// for speed, initialize first with correct size and then copy
counter = 0;
if(init_size > 0) {
dates_=vector<date>(init_size);
elements_=vector<T>(init_size);
}
};
template<class T>dated<T>::dated(const dated<T>& dobs) {
// for speed, initialize first with correct size and then copy
counter = 0;
dates_=vector<date>(dobs.size());
elements_=vector<T>(dobs.size());
for (int t=0;t<dobs.size();++t){
dates_[t] = dobs.date_at(t);
elements_[t] = dobs.element_at(t);
};
};
template<class T> dated<T> dated<T>::operator= (const dated<T>& dobs) {
counter = 0;
if (this==&dobs) return *this; // check against self assignment;
clear();
dates_=vector<date>(dobs.size());
elements_=vector<T>(dobs.size());
for (int t=0;t<dobs.size();++t){
dates_[t] = dobs.date_at(t);
elements_[t] = dobs.element_at(t);
};
return *this;
};
template<class T> dated<T>::~dated();
template<class T> bool dated<T>::empty() const { return (dates_.size()<1); };
template<class T> int dated<T>::size() const { return dates_.size(); };
template<class T> date dated<T>::date_at(const int& t) const { // accessing with bounds checking
if ( (t>=0) && (t<size()) ) return dates_[t];
return date();
};
template<class T> T dated<T>::element_at(const int& t) const { // accessing with bounds checking
if ( (t>=0) && (t<size()) ) return elements_[t];
return T();
};
template<class T> void dated<T>::set_counter(int cntr){
counter = cntr;
}
template<class T> int dated<T>::get_counter() const {
return counter;
}
template<class T> T dated<T>::element_at(const date& d) const {
if (!contains(d)) return T();
return elements_[index_of_date(d)];
};
template <class T> void dated<T>::my_insert(const date& d, const T& obs) {
if (!d.valid()) return;
elements_[counter] = obs;
dates_[counter] = d;
counter++;
};
template<class T> void dated<T>::clear() {
dates_ .erase(dates_ .begin(),dates_ .end());
elements_ .erase(elements_ .begin(),elements_ .end());
};
The dated_observations class:
#ifndef _DATED_OBS_H_
#define _DATED_OBS_H_
#include "dated.h" // templated dated<> class
#include <string> // ANSI string class
class dated_observations : public dated<double>{
private:
string title_;
public:
dated_observations(const dated_observations& dobs); //copy constructor
dated_observations(const int& init_size = 0) : dated<double>(init_size) {;}
void clear();
~dated_observations() { clear(); };
void set_title(string s); // title
string title() const;
int no_obs() const;
int no_obs_between(const date& d1, const date& d2) const;
int no_obs_before(const date& d) const;
int no_obs_after(const date& d) const;
};
///// io
ostream& operator << (ostream&, const dated_observations& );
void print_dated_observations(ostream& of, const dated_observations& d, int precision=3);
//// mischellaneous utilities
double max_obs(dated_observations& dobs);
double min_obs(dated_observations& dobs);
bool dates_match(const dated_observations& obs1, const dated_observations& obs2);
///// picking subsets.
dated_observations observations_between(const dated_observations& obs,const date& first,const date& last);
dated_observations observations_after(const dated_observations& obs, const date& first);
dated_observations observations_before(const dated_observations& obs, const date& last);
dated_observations observations_matching_dates(const dated_observations& obs, const vector<date>& dates);
///// picking periodic elements
dated_observations beginning_of_month_observations(const dated_observations&);
dated_observations end_of_month_observations(const dated_observations&);
dated_observations end_of_year_observations(const dated_observations&);
dated_observations end_of_year_current_observations(const dated_observations&);
#endif
Some of the dated_observations methods:
dated_observations::dated_observations(const dated_observations& dobs) {
elements_ = dobs.elements_;
dates_ = dobs.dates_;
set_counter(dobs.get_counter());
}
void dated_observations::set_title(string s) { title_ = s; };
void dated_observations::clear() {
title_ = string();
dated<double>::clear();
set_counter(0);
};
Another edit:
Removing all the code between the initialization of s1_p & s1_r and the end actually removes the error. Could maybe trying to read or copy a value outside the size of the vector cause this?

Related

L-value interpretation of overloading operator()

While studying graph theory, I wanted to try some code, so I came up with this:
class edge
{
public:
edge(char v1, char v2, int wt = INT_MAX) : vertex1(v1), vertex2(v2), weight(wt) {}
edge(const edge& e)
{
this->vertex1 = e.vertex1;
this->vertex2 = e.vertex2;
this->weight = e.weight;
}
edge& operator=(const edge& e)
{
this->weight = e.weight;
return *this;
}
edge& operator=(const int& w)
{
this->weight = w;
return *this;
}
bool operator==(const edge& e) const
{
const auto res = this->weight == e.weight;
return res;
}
bool is_connected() const { return !(weight == INT_MAX); }
char vertex1;
char vertex2;
int weight;
};
And corresponding graph class:
class graph
{
public:
edge operator ()(const char &i, const char &j) const; // #1
edge& operator ()(const char &i, const char &j); // #2
// More implementations...
private:
std::vector<char> vertices;
std::vector<edge> edges;
};
This allows me to write code like this:
graph g;
g('a', 'b') = 1;
g('a', 'f') = 2;
g('a', 'b') = g('a', 'f'); // #2 is called
g('a', 'b'); // #2 is called
How can I cause #1 to get called? Okay, also it occurs to me that something might be wrong with this construct. Could someone kindly review this code for me? Thanks!
Also, I read this one here, but I need more information.
Overload resolution between these two methods is roughly equivalent to the overload resolution of the following two functions.
edge func(const graph *thiz, const char &i, const char &j); // #1
edge& func(graph *thiz, const char &i, const char &j); // #2
then the following call is fully matched with the #2 because the first argument is not const.
graph g;
func(&g, 'a', 'b');
However if the first argument was const, only #1 can be called.
If you want to do this sort of thing, you need to have your operator() return an edge_ref helper object that can be assigned to (to insert an edge into the graph), or implicitly converted into an edge:
class graph {
std::set<char> vertices;
std::map<std::pair<char, char>, int> edges;
class edge_ref {
graph &self;
char i, j;
public:
edge_ref(graph &g, char i, char j): self(g), i(i), j(j) {}
int operator=(int weight) {
self.vertices.insert(i);
self.vertices.insert(j);
return self.edges[std::make_pair(i, j)] = weight; }
operator int() {
return self.edges.at(std::make_pair(i, j)); }
};
public:
edge_ref operator()(char i, char j) { return edge_ref(*this, i, j); }

Iterator gives different results based on usage c++

I recently started c++ programming. I shifted from Java.
I was building my own Iterable class template like this:
template<class T> class Iterable
{
T start,stop;
public:
explicit Iterable(T s,T e) {start=s; stop=e;;}
public:
virtual void next(T& i) =0;
public:
class iterator: public std::iterator<
std::input_iterator_tag, // iterator_category
T, // value_type
long, // difference_type
const T*, // pointer
T // reference
>{
T current;
Iterable<T>* obj;
public:
explicit iterator(T t,Iterable<T>* o) : obj(o) {current=t;}
iterator& operator++() {obj->next(current); return *this;}
iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
bool operator==(iterator other) const {return current == other.current;}
bool operator!=(iterator other) const {return !(*this == other);}
const T& operator*() const {return current;}
};
iterator begin() {return iterator(start,this);}
iterator end() {return iterator(stop,this);}
};
When i tried to use this iterator, I got different results when invoked differently:
for(auto S=SI.begin();S!=SI.end();S++)
{
cout << *S << "\n";
//cout << contains(seqs,S) << "\n";
if(!contains(seqs,*S))
seqs.push_back(*(new Sequence(*S)));
}
gave different results from:
for(Sequence S : SI)
{
cout << S << "\n";
//cout << contains(seqs,S) << "\n";
if(!contains(seqs,S))
seqs.push_back(*(new Sequence(S)));
}
even in the loop.
My SeqIter class (SI is object of this class) is as follows:
class SeqIter : public flex::Iterable<Sequence>
{
int n;
public:
SeqIter(int s) : Iterable(Sequence(copyList(0,s),s),Sequence(copyList(3,s),s)) {n=s;}
void next(Sequence& s)
{
char ch;
for(int i=0;i<n;i++)
{
ch=nextBase(s[i]);
s[i]=ch;
if(ch!=0)
break;
}
}
};
Sorry if this is too much code, but I do not know how much code is required.
Also, a brief explanation on the Sequence class:
It is a class that has an array of numbers (in this case I tried with 3), and it generates next sequences based on the first, i.e. 000, 100, 200, 300; 010,110 ...
Each digit ranges from 0-3 (both included)
I am unable to understand why both loops give different sequences (first gives 000 100 200 300 010 110 whereas second gives 000 100 200 300 000 110)
I thought both the loops were fundamentally same, and that the first was just the expansion of the second. Is that not so?
Also sequence class: (Sorry for delay, but I guess this is the problem)
class Sequence
{
int size=1;
char* bps;
public:
Sequence() {size=0;}
Sequence(int s)
{
size=s;
bps=new char[s];
}
Sequence(char* arr,int s)
{
size=s;
bps=arr;
}
Sequence(const Sequence& seq)
{
size=seq.size;
bps=new char[size];
strcpy(bps,seq.bps);
}
String toString() const {return *(new String(bps,size));}
inline char* toCharArray() {return bps;}
inline int getSize() const {return size;}
//operator overloading
public:
bool operator==(const Sequence& s2) const
{
if(s2.size!=size)
return false;
String r1=toString();
String r2=s2.toString();
return (r1==r2 || r1==r2.reverse());
}
inline bool operator!=(const Sequence& s2) const {return !operator==(s2);}
const char& operator[](int n) const
{
if(n>=size)
throw commons::IndexOutOfBoundsException(n,size);
return bps[n];
}
char& operator[](int n)
{
if(n>=size)
throw commons::IndexOutOfBoundsException(n,size);
return bps[n];
}
Sequence& operator=(const Sequence& seq)
{
size=seq.size;
bps=new char[size];
strcpy(bps,seq.bps);
}
};
Sorry everyone. Answering my own question after debugging:
In my Sequence class, I was using strcpy in copying char*, where the array did not end with a '\0'
Probably that caused the error:
I read online a bit more to find that the expansion was as follows:
for(Sequence S : seqs)
{
...
}
is equivalent to
for(auto i=SI.begin();i!=SI.end();i++)
{
Sequence S=*i;
...
}
So in the assignment, (S=*i) the data was not properly copied.
Sorry for all the trouble
fixed by removing assignment operator overload, and changing copy-constructor to:
Sequence(const Sequence& seq)
{
size=seq.size;
bps=new char[size];
for(int i=0;i<size;i++)
bps[i]=seq[i];
}

Deriving from pure virtual template class

I belive my problem is simple, yet I cannot manage to overcome it.
I have abstract template class aghContainer and child template class aghVector. I am trying to make aghVector object, but I get an error that I cannot create objects of abstract class. I am pretty sure that I implemented all methods, but maybe I miss something...
aghContainer:
template <typename T>
class aghContainer {
public:
virtual ~aghContainer() {}
virtual void append(T const&) = 0;
virtual void append(aghContainer<T> const& right) = 0;
virtual bool replace(const int, T const&) = 0;
virtual T& at(const int) const = 0;
virtual int size(void) const = 0;
virtual bool remove(const int) = 0;
virtual void clear(void) = 0;
virtual bool isEmpty(void) = 0;
virtual int indexOf(T const& _value, int _from = 0) const = 0;
virtual bool contains(T const& _value, int _from = 0) const = 0;
virtual void print(ostream&) const = 0;
virtual bool equal(aghContainer<T> const& right) const = 0;
virtual bool operator==(aghContainer<T> const& right) const;
virtual bool operator!=(aghContainer<T> const& right) const;
virtual T& operator[](const int n) const;
virtual aghContainer<T>& operator+=(T const& element);
virtual aghContainer<T>& operator+=(aghContainer<T> const& right);
virtual aghContainer<T>& operator<<(T const& element);
virtual aghContainer<T>& operator<<(aghContainer<T> const& right);
friend ostream& operator<<(ostream&, aghContainer<T> const& right);
};
aghVector:
template <typename T>
class aghVector :
public aghContainer<T> {
public:
aghVector();
~aghVector();
void append(T const&);
void append(aghContainer<T> const& right);
bool insert(const int, T const&);
bool replace(const int, T const&);
T& at(const int) const;
int size(void) const;
bool remove(const int);
void clear(void);
bool isEmpty(void);
int indexOf(T const& _value, int _from = 0);
bool contains(T const& _value, int _from = 0) const;
void print(ostream&) const;
bool equal(aghContainer<T> const& right) const;
private:
T* vector;
unsigned int elements;
void destroyVector();
};
Error:
'aghVector': cannot instantiate abstract class Data-Container G:\CPP\Data-Container\ex3main.cpp 101
A couple of problems I can see on a quick look.
In aghContainer
void append(aghContainer<T> const& right) = 0;
and in aghVector
void append(aghVector<T> const& right);
actually overloads the function with a different argument type (since aghVector is a distinct type from aghContainer. The inherited append() will be hidden and not overridden.
A similar problem for equal().
The declaration of indexOf() in aghContainer is const, and the one in aghVector is not. Therefore, again, the version in aghVecvtor hides the inherited function, and does not override it.
From the aghContainer class you have the function
void append(aghContainer<T> const& right) = 0;
Then in the aghVector you have this function:
void append(aghVector<T> const& right);
The problem is that those are two different functions, which means you don't override the parent class append function. leading to aghVector still being an abstract class.

Iterator Implementation - (Linked List Queue)

I am implementing an iterator for a Queue data type, but the iterator is being initialized as a const inside of the class implementation for some reason. I cannot figure out why the constructor is causing the iterator to return itself as a const.
Any feedback as to what the intricasies of the C++ language that may be causing my problem could be, would be very helpful.
The Error I am receiving from Eclipse which seems to be coming from my begin() method is:
../src/linked_queue.hpp:315:35: error: invalid conversion from
'const ics::LinkedQueue<int>*' to 'ics::LinkedQueue<int>*' [-fpermissive]
Interface:
#ifndef LINKED_QUEUE_HPP_
#define LINKED_QUEUE_HPP_
#include <string>
#include <iostream>
#include <sstream>
#include <initializer_list>
#include "ics_exceptions.hpp"
namespace ics {
template<class T> class LinkedQueue {
public:
//Destructor/Constructors
~LinkedQueue();
LinkedQueue ();
LinkedQueue (const LinkedQueue<T>& to_copy);
explicit LinkedQueue (const std::initializer_list<T>& il);
template <class Iterable>
explicit LinkedQueue (const Iterable& i);
//Queries
bool empty () const;
int size () const;
T& peek () const;
std::string str () const; //supplies useful debugging information; contrast to operator <<
//Commands
int enqueue (const T& element);
T dequeue ();
void clear ();
template <class Iterable>
int enqueue_all (const Iterable& i);
//Operators
LinkedQueue<T>& operator = (const LinkedQueue<T>& rhs);
bool operator == (const LinkedQueue<T>& rhs) const;
bool operator != (const LinkedQueue<T>& rhs) const;
template<class T2>
friend std::ostream& operator << (std::ostream& outs, const LinkedQueue<T2>& q);
private:
class LN;
public:
class Iterator {
public:
~Iterator();
T erase();
std::string str () const;
LinkedQueue<T>::Iterator& operator ++ ();
LinkedQueue<T>::Iterator operator ++ (int);
bool operator == (const LinkedQueue<T>::Iterator& rhs) const;
bool operator != (const LinkedQueue<T>::Iterator& rhs) const;
T& operator * () const;
T* operator -> () const;
friend std::ostream& operator << (std::ostream& outs, const LinkedQueue<T>::Iterator& i) {
outs << i.str();
return outs;
}
friend Iterator LinkedQueue<T>::begin () const;
friend Iterator LinkedQueue<T>::end () const;
private:
LN* prev = nullptr;
LN* current;
LinkedQueue<T>* ref_queue;
int expected_mod_count;
bool can_erase = true;
Iterator(LinkedQueue<T>* iterate_over, LN* initial);
};
Iterator begin () const;
Iterator end () const;
private:
class LN {
public:
LN () {}
LN (const LN& ln) : value(ln.value), next(ln.next){}
LN (T v, LN* n = nullptr) : value(v), next(n){}
T value;
LN* next = nullptr;
};
LN* front = nullptr;
LN* rear = nullptr;
int used = 0; //Cache for number of values in linked list
int mod_count = 0; //For sensing any concurrent modifications
//Helper methods
void delete_list(LN*& front);
};
Implementation (I've included only a section of my Iterator code):
template<class T>
auto LinkedQueue<T>::begin () const -> LinkedQueue<T>::Iterator {
return Iterator(this, this->front);
}
template<class T>
auto LinkedQueue<T>::end () const -> LinkedQueue<T>::Iterator {
// return Iterator(this, this->rear);
}
template<class T>
LinkedQueue<T>::Iterator::Iterator(LinkedQueue<T>* iterate_over, LN* initial) {
ref_queue = iterate_over;
expected_mod_count = iterate_over->mod_count;
current = initial;
}
The error is because Iterator begin () const; is marked as const, hence the this used in the function is const as well. So in turn, the compiler gives the error that it cannot convert from a const to non-const.
Given that the function signatures are fixed in this case, to resolve the error, added const will help solve the issue.
You could add const to the constructor signature
Iterator(LinkedQueue<T> const* iterate_over, LN* initial);
And make the member const as well
LinkedQueue<T> const* ref_queue;
Adding the const where required to ensure that members and functions remain const as required is known as being const correct.

why does one code compiles and the other fails?

This code complies:
template <class T>
class A {};
void main () {
A<int> a;
vector<A<int>> vec;
vec.push_back(a);
}
but this doesn't:
void main () {
SharedPointer<int> sp;
vector<SharedPointer<int>> vec;
vec.push_back(sp);
}
I get this error:
error C2558: class 'SharedPointer' : no copy constructor available
or copy constructor is declared 'explicit'
SharedPointer header: (all methodes are implemented in the header)
#include <iostream>
#include "Myexception.h"
using namespace std;
#pragma once
template<class T>
class SharedPointer {
T* ob;
int* refcount;
bool shareable;
int refdown();
int refup();
void markUnshareable();
public:
virtual ~SharedPointer();
SharedPointer():shareable(true);
SharedPointer(T pointee):shareable(true);
SharedPointer(SharedPointer<T>& sp);
SharedPointer operator=(const SharedPointer<T>& sp);
bool operator==(const SharedPointer<T>& sp);
const T& operator[](const int idx) const;
T& operator[](const int idx);
T* operator->() const;
T& operator*() const;
void setOb(T pointee);
const T& getOb() const;
int getRefcount();
bool isShareable();
bool isShared();
};
The problem is that the copy constructor:
SharedPointer(SharedPointer<T>& sp);
can't only be used to copy a const pointer. Add the missing const and all should be fine:
SharedPointer(const SharedPointer& sp); // <T> is harmless, but unnecessary
(You'll also have to fix the syntax errors in the constructor definitions, and you should change the return type of main to int. Removing using namespace std; would also be a good idea.)
Your copy constructor declared
SharedPointer(SharedPointer<T>& sp);
should look like :
SharedPointer(const SharedPointer<T>& sp);
so the compiler will find the missing copy constructor