注册 登录
编程论坛 C++教室

程序崩溃!但是去掉析构函数就没有问题了,求解.......

okokpypy 发布于 2017-06-01 22:15, 3683 次点击
程序代码:
#include <iostream>
using namespace std;

class String
{
public:
    String(){len=0;str=new char[1];str[0]='\0';}
    ~String(){delete []str;len=0;};  //注释掉此行就啥事没有


    friend ostream &operator<<(ostream & o, const String &str){o<<str.str;return o;}
    friend istream &operator>>(istream&i, String &str){i>>str.str;return i;}
  

private:
    unsigned short int len;
    char*str;

};

int main()
{
    String s1;
    cin >> s1;
    cout << s1;
    return 0;
}
7 回复
#2
yangfrancis2017-06-01 22:48
delete str;
可能应该这样,毕竟声明是用的char*, 不是[]
#3
LittleJewel2017-06-01 22:48
可能是没有分配足够空间给它去存入字符串,所以析构的时候出错了

错误:检测到应用程序在堆缓冲区结束后写入内存

你试下分配多点空间再试下
#4
yangfrancis2017-06-02 06:36
发现我解释的逻辑好像有点问题
#5
观海听潮2017-06-02 09:44
str=new char[1];这里分配的空间不够写含有一个字符的字符串,所以写入时一定会占用没有说明分配的空间,若不析构还好,一析构就把没有说明分配的内存空间给析构了,一定会出错
#6
某一天2017-06-02 09:57
这里错了: i>>str.str;

用于保存字符串的内存空间只分配了一个字节的内存:str=new char[1];
在使用 i>>str.str; 的时候系统不会自动给你分配内存,也不会自动给你判断是否超界.这里除非放一个空字符串进去,否则不管你放什么进去都会超界.
C++中超界时,当时不会报错(但实际上已经出错了),等你释放空间的时候就会崩溃.

所以当你不要析构函数时虽然也没报错,但是已经有两个潜在的巨大隐患了:
1.超界,2内存泄漏.

正确的修改思路是,在 >> 里,判断i的长度,释放掉原有内存,重新分配新内存



[此贴子已经被作者于2017-6-2 09:58编辑过]

#7
okokpypy2017-06-02 11:56
我发现根本就不能用cin>>接收字符,因为这货没有审查机制,也没有内存扩充机制,只要使用,立马强制写入,100%越界,根源就是无法事先知道用户输入多少个字符,你开辟10000个字符空间,结果用户输入10001个,立马崩溃!
#8
某一天2017-06-02 14:01
自定义字符串里边的>>运算符不好搞,网上插资料得到的基本上都有问题.
主要是istream中读数据不好搞.开放的std::string源代码中又太复杂,很多东西也无法移植.

或许可以这样:

istream &operator>>(istream &is,String &str){
    char buff[1024]; // 超过1024之后不接收
    is.getline(buff, 1024);

    delete[] str.str;

    str.len = strlen(buff);
    str.str = new char[str.len + 1];

    strcpy_s(str.str, str.len + 1, buff);

    return is;
}

不过这么干似乎也有问题.
1