2017-07-14 46 views
0

基本上标题说什么。我一直在试图用char数组编写我自己的字符串类,而我的代码在Visual Studio中运行时工作正常,但在使用gcc时遇到了问题。当我试图删除我的getData功能(可以在下面看到)我得到的例外是:试图写我自己的字符串类在gcc中得到例外

异常在string.exe在0x6262436B(ucrtbased.dll)抛出:0000005:访问冲突读取位置0xCCCCCCBC。发生 我的代码:

页眉:

#pragma warning(disable:4996) 
#ifndef STRING_STRING_H 
#define STRING_STRING_H 

#include<iostream> 
#include<cstring> 
#include<fstream> 

class String { 
private: 
    char *data; //holds the text 
    size_t maxSize; //maximum number of chars in data 
    size_t currentSize; //current number of chars in data 

    void getData(const char *, size_t maxSize); //sets currentSize to the other char* size and 
               // copies the content of the other char* to data 
public: 
    String(); //default constructor 
    ~String(); //destructor 

    String(const String &); //copy-constructor(from String) 
    String(const char *); //copy-constructor(from char*) 

    String operator=(const String &); //operator= (from string) 
    String operator=(const char *); //operator=(from char*) 

    size_t length() const; //currentSize getter 

    void addChar(const char); //adds a char to the data array 

    void getLine(std::ifstream&,const char); // reads line till deliminator and stores it in this string object(all data previously stored is lost) 

    size_t find(const char*); //searches for text in the string and if found returns the starting position , if not found returns -1; 

    void print() const; //prints the string object to console 

    char* toChar() const; //returns a new allocated char pointer with the text inside (must be deleted afterwards) 
}; 


#endif //STRING_STRING_H 

CPP:

#include "String.h" 


String::String() { 
    currentSize = 0; 
    maxSize = 16; 
    try { 
     data = new char[maxSize]; 
     data[0] = '\0'; 
    } 
    catch (std::bad_alloc &) { 
     std::cerr << "Not enough memory" << std::endl; 
     throw; 
    } 
} 

String::~String() { 
    delete[] data; 
} 

size_t String::length() const { 
    return currentSize; 
} 

String::String(const String &other) { 
    this->maxSize = other.maxSize; 
    getData(other.data, maxSize); 
} 

String::String(const char *other) { 
    this->maxSize = strlen(other) *2; 
    getData(other, maxSize); 
} 

void String::getData(const char *dataSource, size_t maxSize) { 
    currentSize = strlen(dataSource); 
    try { 
     char *newData = new char[maxSize]; 
     delete[] data; 
     data = newData; 
     strcpy(data, dataSource); 
    } 
    catch (std::bad_alloc &) { 
     std::cerr << "Not enough memory" << std::endl; 
     throw; 
    } 
} 


String String::operator=(const String &other) { 
    if (this != &other) { 
     maxSize = other.maxSize; 
     getData(other.data, maxSize); 
    } 
    return *this; 
} 

String String::operator=(const char *other) { 
    if (this->data != other) { 
     maxSize = strlen(other) *2; 
     getData(other, maxSize); 
    } 
    return *this; 
} 

void String::addChar(const char newChar) { 
    if (maxSize == currentSize+1) { 
     maxSize *= 2; 
     getData(this->data, maxSize); 
    } 
    data[currentSize++] = newChar; 
} 

void String::getLine(std::ifstream & is, const char delim='\n') 
{ 
    char temp; 
    while (!is.eof()) 
    { 
     is.get(temp); 
     if (temp == delim) 
      break; 
     else 
      addChar(temp); 
    } 
    return; 
} 

size_t String::find(const char * text) 
{ 
    size_t currPos=-1; 
    bool found = 0; 
    for (size_t i = 0; i < currentSize; i++) 
    { 
     if (data[i] == text[0]) 
     { 
      for (size_t j = i+1; j < currentSize; j++) 
      { 
       if (data[j] == text[j - i]) 
        found = 1; 
       else 
       { 
        found = 0; 
        break; 
       } 
      } 
      if (found == 1) 
      { 
       currPos = i; 
       break; 
      } 
     } 
    } 
    return currPos; 
} 

void String::print() const 
{ 
    for (size_t i = 0; i < currentSize; i++) 
    { 
     std::cout << data[i]; 
    } 
    std::cout << std::endl; 
} 

char * String::toChar() const 
{ 
    char* text= new char[currentSize+1]; 
    for (size_t i = 0; i < currentSize; i++) 
    { 
     text[i] = data[i]; 
    } 
    text[currentSize + 1] = 0; 
    return text; 
} 
+2

如果您在使用'gcc'尝试添加'-ggdb3'标志用于调试该”:

String::String(const String &other) : currentSize(0), maxSize(other.maxSize), data(nullptr) { getData(other.data, maxSize); } 

同样,作为char const*实现构造我将指出你的特定行代码失败。比十六进制地址更容易处理。 – Peri461

+2

一些对设计的小评论。 'getData'看起来更像是它应该被称为'setData'。 'String(const char *)'不是一个拷贝构造函数;复制构造函数复制相同类型的对象。在'String'构造函数中,或者在本地处理错误或者抛出异常;不要通过写出错误消息来部分处理错误,然后重新抛出异常。 –

+0

我觉得只是为了打印和重新抛出bad_alloc而不是一个好主意。这可能是打印会抛出。即使没有,班级的用户也可能不希望班级在他的终端上打印内容。抛出异常的事实应该足够明显。 –

回答

0

你的问题是由未初始化的内存调用delete []引起的。

在复制构造函数中,data成员在调用getData()之前未初始化。在getData()中,您使用的是delete [] data;

您可以在构造函数中初始化datanullptr以避免该问题。

在构造函数的主体之前将所有变量初始化为一些合理的值总是一个好主意。例如。可以实现拷贝构造函数为:

String::String(const char *other) : currentSize(0), 
            maxSize(strlen(other) *2), 
            data(nullptr) 
{ 
    getData(other, maxSize); 
} 
+0

这似乎已经解决了这个问题,而且我应该把它作为一个很好的练习,谢谢! –

+0

@Rostislavstoyanov,不客气。 –