C++ - 检查指针是否指向有效内存(此处不能使用NULL检查)

Mes*_*ode 1 c++ null interpreter pointers

我正在创建脚本语言.当我分配东西时,它会分配东西并返回地址然后我对它做任何事情然后删除它.我无法控制变量,比如在我的lang中创建struct(使用指针和bool来检查指针是否指向有效数据)等等因为它会让我的RAM在RAM中变得更慢更大.

例如:(我的脚本语言很容易被理解.我怀疑你不会理解这一点,但无论如何我会在其中加入一些评论)

MyStruct = { //Function. For create object with it use 'new' before it.
    TestAliveVar=0
}
Func = { //I'll explain what exactly this function does every place it runs.
    if (!exists(arg0)) //C++: ???
        exit;
    arg0.TestAliveVar=1
    println "Still alive!";
}
var MyVar=new MyStruct(); //Returns address of the new object in the heap
                          //and runs on it the `MyStruct` function.
Func(MyVar);              //Sets his 'TestAliveVar' to 1
                          //and prints 'Still Alive!' with new line
delete(MyVar);            //C++: free(MyVar);
Func(MyVar);              //Does nothing
Run Code Online (Sandbox Code Playgroud)

问题是如何创建exists您在此代码中看到的功能.顺便说一下,我可以在这个lang中运行C++代码.

jxh*_*jxh 8

您可以使用shared_ptr<>来保持指针,并用于weak_ptr<>将指针传递给对象的使用者.你delete摧毁的目标shared_ptr<>对象,然后所有的weak_ptr<>旨意成为过期.

std::weak_ptr<int> wptr;
assert(wptr.expired());
{
    std::shared_ptr<int> intptr(new int);
    wptr = intptr;
    assert(!wptr.expired());
}
assert(wptr.expired());
Run Code Online (Sandbox Code Playgroud)

因此,您的exists检查是检查是否weak_ptr<>已过期.

为了使构造的用法更具体:

Script code                 Hypothetical C++ code that gets executed
----                        ----
var MyVar=new MyStruct();   var_map["MyVar"]
                                = std::shared_ptr<Obj>(new Obj("MyStruct"));
Func(MyVar);                invoke("Func", std::weak_ptr<Obj>(var_map["MyVar"]));
exists(arg0)                !args[0].expired()
delete(MyVar);              var_map.erase("MyVar");
Run Code Online (Sandbox Code Playgroud)

如果脚本要在多线程环境中运行,那么weak_ptr<>状态是一个关键部分.


MvG*_*MvG 5

检测存储器是否不再存在可以例如通过维持一组已知的死指针来完成.您创建的任何指针都会添加到活动集中,当您删除该对象时,您将指针移动到设置.

真正棘手的部分将是重用内存.如果要为不同的对象重用相同的地址,该怎么办?你不能通过查看指针来判断,因为指针看起来是一样的.因此,除非您不想重复使用内存,否则您必须更改您的要求.

  1. 一种可能的方式是结构中的附加字段.我知道你说你不希望这样,但很多评论已经表明这是最好的解决方案,我倾向于同意.
  2. 另一种可能的方法是添加一个间接层,这样你就不会真正传递指向对象的指针,而是将索引转换为生命对象列表或其他任何东西.
  3. 您还可以考虑引用计数和垃圾回收.这样,当没有人再引用它们时,对象才会被删除.相当多的工作,但作为脚本语言的用户,我希望它提供垃圾收集.