Jun 15, 2014 at 2:46am UTC
If you are only getting question marks on the backtrace for GDB, you are probably using an optimized build or haven't enabled debugging symbols. Remove all your -O flags and add a -g flag, and you should be write.
Also, you haven't given us enough information for us to tell - it looks fine from what we can see.
Jun 15, 2014 at 7:48am UTC
I've used -O and -g and it still has question marks.
Jun 15, 2014 at 8:20am UTC
You should tell more about the class String
. Does it "own" dynamically allocated memory? What about the three (copy ctor, copy assignment, dtor)?
Jun 15, 2014 at 8:37am UTC
I'm not sure what's relevant so I'll post all of it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
//String.cpp
#include "String.h"
#include <iostream>
#include <stdexcept>
//constructors
String::String ()
{
internal_string = NULL;
set_length(0);
}
String::String (const char * str)
{
set_str(str);
}
String::String (const String& str)
{
internal_string = str.internal_string; //copy existing pointer
set_str(internal_string);
}
//destructor
String::~String ()
{
delete internal_string;
}
//public functions
long long int String::length()
{
return internal_length;
}
//op overloading
String& String::operator = (const char * str)
{
set_str(str);
}
String& String::operator = (const String& str)
{
set_str(internal_string);
//return &str;
}
String& String::operator += (const char * str)
{
char *temp_str = add (internal_string,str);
set_str(temp_str);
delete temp_str;
}
String& String::operator += (const String& str)
{
char *temp_str = add (internal_string,str.internal_string);
set_str(temp_str);
delete temp_str;
}
char & String::operator [] (const int & i)
{
return internal_string [i];
}
std::ostream& operator << (std::ostream& out,const String& str)
{
out << str.internal_string;
}
//private functions
void String:: set_length (long long int len)
{
internal_length = len;
}
void String:: set_str (const char * str)
{
set_length(get_length(str)); //ensure length set
delete internal_string; //delete any old str
internal_string = new char [internal_length + 1]; //create new str + 1 for null
for (int i=0; i < internal_length + 1; i ++) //copy string
{
internal_string[i] = str[i];
}
}
char * String::add (const char * str1,const char * str2)
{
//temp str
char * temp_str = new char [get_length(str1) + get_length(str2) + 1];
//copy
for (int i=0; i < get_length(str1);i++)
temp_str[i] = str1 [i];
for (int i =0; i < get_length(str2) + 1; i++)
temp_str[i + get_length(str1)] = str2[i];
return temp_str;
}
//public functions
const char * String::c_str()
{
return internal_string;
}
long long int String:: get_length(const char * str)
{
long long int len;
for ( len=0; ;len++)
if (str[len] == '\0' )
break ;
return len;
}
String String::substr(size_t pos, size_t len)
{
if (pos > internal_length)
throw std::out_of_range ("pos is OUT OF RANGE" );
if (pos == internal_length)
return String ("" );
for (int i = pos,l=0; (i < internal_length) && (l < len); i++,l++)
{
//temp [l] = internal_string[i];
//std::cout << internal_string[i];
//std::cout << i << "---"<<l<<std::endl;
}
return "abcd" ;
}
Last edited on Jun 15, 2014 at 8:51am UTC
Jun 15, 2014 at 9:46am UTC
Okay. We have a test case that does crash:
1 2 3 4 5 6 7 8
String foo() {
String temp("abcd" );
return temp;
}
int main() {
String bar = foo();
}
What do we call there?
Line 2 uses String:::String(const char *) for 'temp'
Line 7 uses String::String(const String &) for 'bar { temp }'
Line 4 uses String::~String() for 'temp'
What will those do?
(I will inline some code and omit other nonessential bits.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
String::String (const char * str)
{
internal_length = get_length(str); // length == 4
internal_string = new char [internal_length + 1];
for (int i=0; i < internal_length + 1; i ++) {
internal_string[i] = str[i];
}
// internal_string == "abcd"
}
String::String (const String& str)
{
internal_string = str.internal_string; // both pointers point to same memory block
internal_length = str.internal_length;
delete internal_string; // That one memory block is gone
// str.internal_string is invalid
// copy from str.internal_string is invalid, CRASH?
}
String::~String ()
{
delete internal_string; // temp attempts to deallocate already deallocated space. CRASH
}
Last edited on Jun 15, 2014 at 9:46am UTC