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

存在堆内存中的值去哪里了呢?(注释中红色字体标注)

hulianggen 发布于 2018-12-24 14:59, 2043 次点击
程序代码:
#include"stdafx.h"
#include<iostream>

using namespace std;

int* newPointerGet(int* p1)
{
    int k1 = 55;
    p1 = new int;
    *p1 = k1;
    return p1;
}

int* PointerGet(int* p2)
{
    int k2 = 55;
    p2 = &k2;
    return p2;
}

int main()
{
    cout << "输出函数各自返回指针所指向的内存的值" << endl;
    int* p = NULL;
    p = newPointerGet(p);
    int* i = NULL;
    i = PointerGet(i);
    cout << "newGet:" << *p<<endl ;
    cout << "Get:" << *i << endl;//*i 的值不是55,显示为:260090768,每次编译显示的值还不一样。
    cout << "i 所指向的内存没有被立刻销毁,执行一个输出语句后:" << endl;
    cout << "newGet:" << *p << endl;
    cout << "get:" << *i << endl;
    delete p;
    cout << "销毁内存后:" << endl;
    cout << "newGet:" << *p << endl;
    return 0;
}



3 回复
#2
rohalloway2018-12-24 16:26
*PointerGet(i) 是取值, PointerGet(i) 返回的是地址
你把地址存给i,然后解引用之后为什么出现地址而不是值,我也不清楚,等高手来解答

delete p;
cout << "销毁内存后:" << endl;
cout << "newGet:" << *p << endl; //p已经删除了,这里属于非法访问

[此贴子已经被作者于2018-12-24 22:36编辑过]

#3
Jonny02012018-12-24 22:17
当 PointerGet 函数, k2 变量会被立即释放, 当变量被释放的时候, 内存中的数据已经发生解构, 而且内存已经被系统回收了
也就是说, 即使你得到了 k2 变量的地址, 但是 k2 已经被解构了, 所以它可能是原来的值, 也可能不再是原来的值 (对于 Clang 来说, k2 可能还是原来的值, 因为 k2 属于内置型别)
这种可能, 在 C++ 里面被称作未定行为, 到底是不是原来的值由编译器厂商说了算
你用的可能不是 Clang, 可能是 MSVC 这种编译器, 当 k2 被解构的时候, 值也会随之解构
而未定行为带来的结果, 也就是值的不确定
所以就会出现你所说的值每次都不一样, 因为内存的是悬吊的, 通俗一点, 获得的这个指针叫做野指针

另外, 返回一个指针, 由客端手动释放这样的写法是不推荐的, 最好回传一个智能指针
#4
rohalloway2018-12-24 22:35
以下是引用Jonny0201在2018-12-24 22:17:33的发言:

当 PointerGet 函数, k2 变量会被立即释放, 当变量被释放的时候, 内存中的数据已经发生解构, 而且内存已经被系统回收了
也就是说, 即使你得到了 k2 变量的地址, 但是 k2 已经被解构了, 所以它可能是原来的值, 也可能不再是原来的值 (对于 Clang 来说, k2 可能还是原来的值, 因为 k2 属于内置型别)
这种可能, 在 C++ 里面被称作未定行为, 到底是不是原来的值由编译器厂商说了算
你用的可能不是 Clang, 可能是 MSVC 这种编译器, 当 k2 被解构的时候, 值也会随之解构
而未定行为带来的结果, 也就是值的不确定
所以就会出现你所说的值每次都不一样, 因为内存的是悬吊的, 通俗一点, 获得的这个指针叫做野指针

另外, 返回一个指针, 由客端手动释放这样的写法是不推荐的, 最好回传一个智能指针



茅塞顿开,K2没有了
1