Program crash when calling std::vector.push_back

时间:2017-03-26 19:14:42

标签: c++ vector

I have been learning c++ recently, and for some practice in the language I decided to make and implementation of a sting similar to that of Java in c++. Everything was going smoothly until my split(vector<String> &dest, char delim) function was causing my program to crash. I found that the error was caused by adding a String to the vector, and I could reproduce the error like so:

const String s("abcdefg");
dest.push_back(s);

I'm also particularly concerned about this error because it causes my computer to make a grinding sound until the program crashes.

Note that every other method in the String class works as far as I have tested, this question is only about why my program crashes when adding to the vector.

The String class implementation (although I think most of the code is not needed):

#include <string.h>
#include <iostream>
#include <vector>

#include "jstring.h"

using namespace std;

CharArray::CharArray() {
    length = 0;
    _value = new char[0];
}

CharArray::CharArray(int len) {
    length = len;
    _value = new char[len];
}

CharArray::CharArray(char* value, int len) {
    length = len;
    _value = new char[len];
    for(int i = 0;i < len;++ i) {
        _value[i] = value[i];
    }
}

CharArray::CharArray(const char* value, int len) {
    length = len;
    _value = new char[len];
    for(int i = 0;i < len;++ i) {
        _value[i] = value[i];
    }
}

CharArray::~CharArray() {
    delete[] _value;
}

char* CharArray::native_value() {
    return _value;
}

char& CharArray::operator[](const int index) {
    if(check_index(index)) {
        return _value[index];
    }
    return _value[0];
}

inline bool CharArray::check_index(int i) {
    return i > 0 && i < length;
}

String::String() {
    __str = new CharArray();
}

String::String(const char* str) {
    __str = new CharArray(str, strlen(str));
}

String::String(char* str) {
    __str = new CharArray(str, strlen(str));
}

String::String(std::string str) {
    __str = new CharArray(str.c_str(), str.size());
}

inline void String::dltval() {
    delete __str;
    __str = 0;
}

String::~String() {
    dltval();
}

int String::length() {
    return __str->length;
}

bool String::empty() {
    return __str->length == 0;
}

void String::get_chars(int srcpos, char* dest, int destpos, int len) {
    if(len > __str->length)
        return;
    int dpo = 0;
    for(int i = srcpos;i < len;++ i, ++ dpo) {
        dest[destpos + dpo] = (*__str)[i];
    }
}

void String::get_all_chars(int srcpos, char* dest, int destpos) {
    get_chars(srcpos, dest, destpos, __str->length);
}

bool String::equals(const char* str) {
    if(__str->length != strlen(str))
        return false;
    for(int i = 0;i < strlen(str);++ i) {
        if((*__str)[i] != str[i])
            return false;
    }
    return true;
}

bool String::equals_ignore_case(const char* str) {
    if(__str->length != strlen(str))
        return false;
    for(int i = 0;i < strlen(str);++ i) {
        char c1 = str[i], c2 = (*__str)[i];
        if(c1 >= 97 && c1 <= 122 || c2 >= 97 && c2 <= 122) {
            if(c1 >= 97 && c1 <= 122)
                c1 = (char)(((int)c1) - 32);
            if(c2 >= 97 && c1 <= 122)
                c2 = (char)(((int)c2) - 32);
            if(c1 != c2)
                return false;
        }else{
            if(c1 != c2)
                return false;
        }
    }
    return true;
}

bool String::starts_with(const char* str) {
    if(strlen(str) > __str->length)
        return false;
    if(strlen(str) == __str->length)
        return equals(str);
    for(int i = 0;i < strlen(str);++ i) {
        if(str[i] != (*__str)[i])
            return false;
    }
    return true;
}

bool String::ends_with(const char* str) {
    if(strlen(str) > __str->length)
        return false;
    if(strlen(str) == __str->length)
        return equals(str);
    for(int i = __str->length - strlen(str), j = 0;i < __str->length;++ i, ++ j) {
        if(str[j] != (*__str)[i])
            return false;
    }
    return true;
}

int String::index_of(char c) {
    for(int i = 0;i < __str->length;++ i) {
        if((*__str)[i] == c)
            return i;
    }
    return -1;
}

int String::index_of(const char* str) {
    if(strlen(str) == 0)
        return -1;
    int j = 0, k = 0;
    for(int i = 0;i < __str->length;++ i) {
        if((*__str)[i] != str[j]) {
            j = 0;
            continue;
        }else{
            if(j == 0)
                k = i;
        }
        ++ j;
        if(j == strlen(str))
            return k;
    }
    return -1;
}

int String::last_index_of(char c) {
    int j = -1;
    for(int i = 0;i < __str->length;++ i) {
        if((*__str)[i] == c)
            j = i;
    }
    return j;
}

int String::last_index_of(const char* str) {
    if(strlen(str) == 0)
        return -1;
    int j = 0, k = 0, l = -1;
    for(int i = 0;i < __str->length;++ i) {
        if((*__str)[i] != str[j]) {
            j = 0;
            continue;
        }else{
            if(j == 0)
                k = i;
        }
        ++ j;
        if(j == strlen(str))
            l = k;
    }
    return l;
}

String String::substring(int begin) {
    int len = __str->length - begin;
    char *substr = new char[len];
    for(int i = begin, j = 0;i < __str->length;++ i, ++ j) {
        substr[j] = (*__str)[i];
    }
    String ret(substr);
    delete[] substr;
    return ret;
}

String String::substring(int begin, int end) {
    if(end <= begin)
        throw "Index out of bounds";
    int len = end - begin;
    char *substr = new char[len];
    for(int i = begin, j = 0;i < end;++ i, ++ j) {
        substr[j] = (*__str)[i];
    }
    String ret(substr);
    delete[] substr;
    return ret;
}

String String::concat(const char* str) {
    int nlen = __str->length + strlen(str);
    char *cc = new char[nlen];
    int j = 0;
    for(int i = 0;i < __str->length;++ i) {
        cc[j] = (*__str)[i];
        ++ j;
    }
    for(int i = 0;i < strlen(str);++ i) {
        cc[j] = str[i];
        ++ j;
    }
    String ret(cc);
    delete[] cc;
    return ret;
}

void String::replace(int start, const char* str, int olen) {
    char *nstr = new char[__str->length + (strlen(str) - olen)];
    for(int i = 0;i < start;++ i) {
        nstr[i] = (*__str)[i];
    }
    if(strlen(str) != 0) {
        for(int i = start, j = 0;i < start + strlen(str);++ i, ++ j) {
            nstr[i] = str[j];
        }
    }
    for(int i = start + olen, j = start + strlen(str);i < __str->length;++ i, ++ j) {
        nstr[j] = (*__str)[i];
    }
    int osize = __str->length;
    dltval();
    __str = new CharArray(nstr, osize + (strlen(str) - olen));
    delete[] nstr;
}

String& String::replace(char ch, char newChar) {
    for(int i = 0;i < __str->length;++ i) {
        if((*__str)[i] == ch)
            (*__str)[i] = newChar;
    }
    return *this;
}

String& String::replace_all(const char* str, const char* nstr) {
    String _nstr(__str->native_value());
    int j = 0, k = 0, c = 0;
    for(int i = 0;i < __str->length;++ i) {
        if((*__str)[i] == str[j] && j == 0) {
            k = i;
        }else if((*__str)[i] != str[j] && j != 0 && (*__str)[i] == str[0]) {
            k = i;
            j = 0;
        }else if((*__str)[i] != str[j]) {
            j = 0;
            continue;
        }
        ++ j;
        if(j == strlen(str)) {
            _nstr.replace(k + c * (strlen(nstr) - strlen(str)), nstr, strlen(str));
            ++ c;
            j = 0;
        }
    }
    int olen = __str->length;
    dltval();
    __str = new CharArray(_nstr.c_str(), olen +  c * (strlen(nstr) - strlen(str)));
    return *this;
}

String& String::remove(char ch) {
    char *nstr = new char[__str->length];
    int j = 0;
    for(int i = 0;i < __str->length;++ i) {
        if((*__str)[i] != ch) {
            nstr[j] = (*__str)[i];
            ++ j;
        }
    }
    dltval();
    __str = new CharArray(nstr, j);
    delete[] nstr;
    return *this;
}

String& String::remove_all(const char* str) {
    replace_all(str, "");
    return *this;
}

bool String::contains(const char* str) {
    return index_of(str) != -1;
}

void String::split(std::vector<String> &dest, char ch) {

}

void String::split(vector<String> &dest, const char* str) {

}

String& String::to_uc() {
    for(int i = 0;i < __str->length;++ i) {
        int cp = ((int)(*__str)[i]);
        if(cp >= 97 && cp <= 122) {
            cp -= 32;
        }
        (*__str)[i] = ((char)cp);
    }
    return *this;
}

String& String::to_lc() {
    for(int i = 0;i < __str->length;++ i) {
        int cp = ((int)(*__str)[i]);
        if(cp >= 65 && cp <= 90) {
            cp += 32;
        }
        (*__str)[i] = ((char)cp);
    }
    return *this;
}

String String::trim() {
    int st = 0, len = __str->length;
    while((st < len) && (*__str)[st] <= 32) {
        ++ st;
    }
    while((st < len) && (*__str)[len - 1] <= 32) {
        -- len;
    }
    return substring(st, len);
}

CharArray& String::get_chars() {
    return *__str;
}

char* String::c_str() {
    return __str->native_value();
}

char& String::operator[](const int index) {
    return (*__str)[index];
}

ostream& operator<<(ostream &out, const String &str) {
    for(int i = 0;i < str.__str->length;++ i) {
        out << (*str.__str)[i];
    }
    return out;
}

What I used to reproduce the crash:

#include <iostream>
#include <cstdlib>
#include <vector>
#include "jstring.h"

using namespace std;

void add_to_vec(vector<String> &dest) {
    const String s("abcdefg");
    dest.push_back(s);
}

int main(int argc, char **argv) {
    vector<String> strs;

    add_to_vec(strs);

    return EXIT_SUCCESS;
}

0 个答案:

没有答案