关于实例化的问题

时间:2022-01-25 05:06:43
class T{
public:
void f(){cout<<"b"<<endl;};
};
int main(){
T *b = new T;
b->f();
delete b;
b->f();
return 0;
}

为什么delete释放内存之后,还能访问类的方法?

请问delete释放与没有释放内存有什么区别?

T *b = new T;
b->f();

T b;
b.f();
这两种实例化有什么区别呢?

12 个解决方案

#1


1.delete后内存并没有被改写,只是被标记为“可用”。这样的操作是不可预料的。
2.一个在堆上,一个在栈上。

#2


引用 1 楼 lsldd 的回复:
1.delete后内存并没有被改写,只是被标记为“可用”。这样的操作是不可预料的。
2.一个在堆上,一个在栈上。

第1个回答,只是标记“可用”是什么意思,觉得还是听不懂……

#3


能以比较有说服力的理论来论证吗?

#4


标记就是告诉操作系统这块内存我不用了你可以随便支配了(比如分配给其他内存需要者)。
然而如果接下来没有人去用这块内存,那这内存的内容还是保持原样,你依然可以调用。
执行过delete操作后的指针叫野指针,是非常危险的...
所以delete一个内存后必须将指针置空。

#5


引用 4 楼 lsldd 的回复:
标记就是告诉操作系统这块内存我不用了你可以随便支配了(比如分配给其他内存需要者)。
然而如果接下来没有人去用这块内存,那这内存的内容还是保持原样,你依然可以调用。
执行过delete操作后的指针叫野指针,是非常危险的...
所以delete一个内存后必须将指针置空。

明白了!  

T *b = new T;  这是在堆上分配
T b;           这是在栈上分配

delete 负责释放堆上分配的内存,这样理解对吗?

#6


#7


成员函数在调用时,只是比普通函数多了this指针入栈,如果成员函数访问成员变量,就根据隐式传入指针值+成员变量在对象中的偏移(编译期确定)确定成员变量的地址。所以此时this值的必须是有效的,否则this+偏移时访问成员变量可能会有错误。如果成员函数中没有访问成员变量的话,那么传入的this指针的值没有啥用处了,可以为任意值。

nt main()

    T *b = new T; 
    b->f(); //这是没有问题的。
    delete b; //delete b只是把b的值对应的内存标记成不可用,但并没有改变指针变量b的值
    b->f(); //此时隐式传入的this值和 T *b = new T; 一样,虽然this值现在已不是有效,但由于
             //成员函数未访问成员变量,所以运行时也没啥问题
    ((T*)(10000))->f();//同上原因,也没有问题
    return 0; 

#8


希望下面这个对你有用,delete的效果和free差不多:
http://www.diybl.com/course/3_program/c++/cppjs/2008828/138349.html

不过有个有趣的现象,如果函数没有使用成员变量,即使是指向null,也是可以调用的:
应该是因为类函数的地址实际是固定的,跟实例没有关系,编译期间就确定了函数的入口,所以没有问题。
如果函数使用到成员变量的话,还是很容易导致异常的。



#include <iostream>
#include <string>
using namespace std;

class t
{
public:
    void f();
};

void t::f()
{
    cout << 't' << endl;
}

int main()
{
    t* tt = new t;
    tt->f();
    delete tt;
    tt->f();
    tt = 0;
    tt->f();
    return 0;
}




#9


在C++ 中 delete * b; 后 一般还加一句  b=NULL ; 

#10


请教楼上各位:

对于标准库中的allocator类假设已使用allocator的一个对象分配了一段空间,并使用相应的函数给了所有元素初始值。想请问,能不能不使用allocator类的destroy函数先将元素删除,而直接使用deallocate函数来将空间归还给系统,这样做可以吗?如果不能,为什么呢?

#11


还是觉得1楼讲解的比较合理

#12


7楼说的更有针对性。学习

#1


1.delete后内存并没有被改写,只是被标记为“可用”。这样的操作是不可预料的。
2.一个在堆上,一个在栈上。

#2


引用 1 楼 lsldd 的回复:
1.delete后内存并没有被改写,只是被标记为“可用”。这样的操作是不可预料的。
2.一个在堆上,一个在栈上。

第1个回答,只是标记“可用”是什么意思,觉得还是听不懂……

#3


能以比较有说服力的理论来论证吗?

#4


标记就是告诉操作系统这块内存我不用了你可以随便支配了(比如分配给其他内存需要者)。
然而如果接下来没有人去用这块内存,那这内存的内容还是保持原样,你依然可以调用。
执行过delete操作后的指针叫野指针,是非常危险的...
所以delete一个内存后必须将指针置空。

#5


引用 4 楼 lsldd 的回复:
标记就是告诉操作系统这块内存我不用了你可以随便支配了(比如分配给其他内存需要者)。
然而如果接下来没有人去用这块内存,那这内存的内容还是保持原样,你依然可以调用。
执行过delete操作后的指针叫野指针,是非常危险的...
所以delete一个内存后必须将指针置空。

明白了!  

T *b = new T;  这是在堆上分配
T b;           这是在栈上分配

delete 负责释放堆上分配的内存,这样理解对吗?

#6


#7


成员函数在调用时,只是比普通函数多了this指针入栈,如果成员函数访问成员变量,就根据隐式传入指针值+成员变量在对象中的偏移(编译期确定)确定成员变量的地址。所以此时this值的必须是有效的,否则this+偏移时访问成员变量可能会有错误。如果成员函数中没有访问成员变量的话,那么传入的this指针的值没有啥用处了,可以为任意值。

nt main()

    T *b = new T; 
    b->f(); //这是没有问题的。
    delete b; //delete b只是把b的值对应的内存标记成不可用,但并没有改变指针变量b的值
    b->f(); //此时隐式传入的this值和 T *b = new T; 一样,虽然this值现在已不是有效,但由于
             //成员函数未访问成员变量,所以运行时也没啥问题
    ((T*)(10000))->f();//同上原因,也没有问题
    return 0; 

#8


希望下面这个对你有用,delete的效果和free差不多:
http://www.diybl.com/course/3_program/c++/cppjs/2008828/138349.html

不过有个有趣的现象,如果函数没有使用成员变量,即使是指向null,也是可以调用的:
应该是因为类函数的地址实际是固定的,跟实例没有关系,编译期间就确定了函数的入口,所以没有问题。
如果函数使用到成员变量的话,还是很容易导致异常的。



#include <iostream>
#include <string>
using namespace std;

class t
{
public:
    void f();
};

void t::f()
{
    cout << 't' << endl;
}

int main()
{
    t* tt = new t;
    tt->f();
    delete tt;
    tt->f();
    tt = 0;
    tt->f();
    return 0;
}




#9


在C++ 中 delete * b; 后 一般还加一句  b=NULL ; 

#10


请教楼上各位:

对于标准库中的allocator类假设已使用allocator的一个对象分配了一段空间,并使用相应的函数给了所有元素初始值。想请问,能不能不使用allocator类的destroy函数先将元素删除,而直接使用deallocate函数来将空间归还给系统,这样做可以吗?如果不能,为什么呢?

#11


还是觉得1楼讲解的比较合理

#12


7楼说的更有针对性。学习