none
小白对于指针释放问题的疑惑 RRS feed

  • 问题

  • MyString.h

    #pragma once
    #ifndef MYSTRING_H
    #define MYSTRING_H
    #include "iostream"
    class MyString
    {
    private:
    	char * str;
    	int length;
    public:
    	MyString();
    	MyString(const char *);
    	MyString(const MyString &);
    	~MyString();
    	MyString GetSring(int,int);
    };
    #endif
    

    MyString.cpp

    #include "stdafx.h"
    #include "MyString.h"
    #include "iostream"
    
    #define DELETE_POINTER(p)  if(p){delete (p);(p)=NULL;}
    
    MyString::MyString()
    {
    	length = 0;
    	str = new char[1];
    	str[0] = '\0';
    }
    MyString::MyString(const char * c)
    {
    	DELETE_POINTER(str);
    	length = std::strlen(c);
    	str = new char[length+1];
    	strcpy_s(str,length+1,c);
    }
    
    MyString::MyString(const MyString & mStr)
    {
    	DELETE_POINTER(str);
    	length = std::strlen(mStr.str);
    	str = new char[length + 1];
    	strcpy_s(str, length+1, mStr.str);
    }
    
    MyString::~MyString()
    {
    	DELETE_POINTER(str);
    }
    
    MyString MyString::GetSring(int start_index, int end_index)
    {
    	int dis = end_index - start_index;
    	if (dis > 0)
    	{
    		char * c = new char[dis +1];
    		for (int i = start_index,j = 0; i <= end_index && j <= dis;i++,j++)
    		{
    			c[j] = str[i];
    		}
    		c[dis] = '\0';
    		MyString ret(c);
    		delete[] c;
    		return ret;
    	}
    	else
    	{
    		return NULL;
    	}
    }
    

    main.cpp

    #include "stdafx.h"
    #include "iostream"
    #include "MyString.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	MyString str1("Hello World");
    	str1.GetSring(1,9);
    
    	system("PAUSE");
    	return 0;
    }
    

    如上,运行时会报错:读取位置0xCCCCCCC0时发生访问冲突

    这可能是对未初始化的指针str进行DELETE_POINTER释放操作时导致的。

    但是当我将GetString的返回值赋值给另一个新的MyString对象时,却不会出现问题:

    #include "stdafx.h"
    #include "iostream"
    #include "MyString.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	MyString str1("Hello World");
    	MyString str2 = str1.GetSring(1,9);
    
    	std::cout << "\n";
    	system("PAUSE");
    	return 0;
    }
    
    环境是win8.1+VS 2013.
    请问这是为什么?最好可以详细解释一下,谢谢!



    2015年4月27日 2:32

答案

  • ?????
    • 已标记为答案 Shu 2017 2015年5月11日 1:30
    • 已编辑 Shi Xin 2015年7月27日 6:21
    2015年4月27日 6:42
  • MyString str1("Hello World");
    MyString str2 = str1.GetSring(1,9);

    这样写一样有问题,第一句调用MyString的构造函数
    MyString::MyString(const char * c)第一句就会出错。
    第二句
    MyString str2 = str1.GetSring(1,9)会调用MyString的拷贝构造函数,运行到里面的第一句仍然会出错。

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 Shu 2017 2015年5月11日 1:29
    2015年4月27日 10:10
    版主

全部回复

  • ?????
    • 已标记为答案 Shu 2017 2015年5月11日 1:30
    • 已编辑 Shi Xin 2015年7月27日 6:21
    2015年4月27日 6:42
  • 成员变量全部都没有初始化。而且在构造函数里进行delete是毫无意义的,还没初始化为什么要销毁?

    MyString::MyString() :
    length(0),
    str(new char[]{'\0'})
    {}
    
    MyString::MyString(const char * c) :
    length(std::strlen(c)),
    str(new char[length+1])
    {
    	strcpy_s(str,length+1,c);
    }
    
    MyString::MyString(const MyString & mStr) :
    length(std::strlen(mStr.str),
    str(new char[length+1])
    {
    	strcpy_s(str, length+1, mStr.str);
    }


    Shi Xin

    但是当我将GetString的返回值赋值给另一个新的MyString对象时,却不会出现问题,这是为什么呢?
    2015年4月27日 7:06
  • MyString str1("Hello World");
    MyString str2 = str1.GetSring(1,9);

    这样写一样有问题,第一句调用MyString的构造函数
    MyString::MyString(const char * c)第一句就会出错。
    第二句
    MyString str2 = str1.GetSring(1,9)会调用MyString的拷贝构造函数,运行到里面的第一句仍然会出错。

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 Shu 2017 2015年5月11日 1:29
    2015年4月27日 10:10
    版主
  • 谢谢,但是我的VS 2013没有报错,很奇怪
    2015年4月28日 9:29