标签: dangling-pointer

可以在其范围之外访问局部变量的内存吗?

我有以下代码.

#include <iostream>

int * foo()
{
    int a = 5;
    return &a;
}

int main()
{
    int* p = foo();
    std::cout << *p;
    *p = 8;
    std::cout << *p;
}
Run Code Online (Sandbox Code Playgroud)

而代码只是运行而没有运行时异常!

输出是 58

怎么会这样?本地变量的内存不能在其功能之外无法访问吗?

c++ memory-management local-variables dangling-pointer

990
推荐指数
19
解决办法
26万
查看次数

弱引用和无引用引用之间有什么区别?

斯威夫特有:

  • 强引用
  • 弱参考
  • 无主参考文献

无主参考如何与弱参考不同?

什么时候使用无主参考安全?

无主引用是否存在安全风险,如C/C++中的悬空指针

memory-management weak-references automatic-ref-counting dangling-pointer swift

232
推荐指数
4
解决办法
7万
查看次数

比较悬空指针是否合法?

比较悬空指针是否合法?

int *p, *q;
{
    int a;
    p = &a;
}
{
    int b;
    q = &b;
}
std::cout << (p == q) << '\n';
Run Code Online (Sandbox Code Playgroud)

注意如何既pq点有对象已经消失了.这合法吗?

c++ pointers language-lawyer dangling-pointer

70
推荐指数
1
解决办法
2392
查看次数

什么是悬垂指针?

我知道这是很常见的问题,但对我来说还是新的!

我不明白悬挂指针的概念,谷歌搜索,并编写测试方法找到一个.

我只是想知道这是一个悬垂的指针吗?无论我发现什么样的东西都回来了,我在这里尝试类似的东西!

谢谢!

void foo(const std::string name)
{
    // will it be Dangling pointer?!, with comments/Answer
    // it could be if in new_foo, I store name into Global.
    // Why?! And what is safe then?
    new_foo(name.c_str());
}

void new_foo(const char* name)
{
    // print name or do something with name...   
}
Run Code Online (Sandbox Code Playgroud)

c++ pointers dangling-pointer

43
推荐指数
5
解决办法
5万
查看次数

我们可以在C中返回字符串文字

这段代码有效吗?

const char* foo() {
  return "Hello World";
}
Run Code Online (Sandbox Code Playgroud)

也就是说,从C函数返回"Hello World".

const char* str = foo();
Run Code Online (Sandbox Code Playgroud)

str是一个悬垂的指针吗?

PS:上面的函数是从一些实际代码中抽象出来的.我看到有人编写直接返回字符串文字的代码.

c c++ pointers dangling-pointer

38
推荐指数
0
解决办法
2503
查看次数

使用numpy/ctypes公开C分配内存缓冲区的更安全方法?

我正在为一个C库编写Python绑定,该库使用共享内存缓冲区来存储其内部状态.这些缓冲区的分配和释放是由Python本身在Python之外完成的,但我可以通过从Python中调用包装的构造函数/析构函数来间接控制何时发生这种情况.我想将一些缓冲区暴露给Python,以便我可以从它们中读取,并在某些情况下将值推送给它们.性能和内存使用是重要的问题,因此我希望尽可能避免复制数据.

我目前的方法是创建一个numpy数组,提供对ctypes指针的直接视图:

import numpy as np
import ctypes as C

libc = C.CDLL('libc.so.6')

class MyWrapper(object):

    def __init__(self, n=10):
        # buffer allocated by external library
        addr = libc.malloc(C.sizeof(C.c_int) * n)
        self._cbuf = (C.c_int * n).from_address(addr)

    def __del__(self):
        # buffer freed by external library
        libc.free(C.addressof(self._cbuf))
        self._cbuf = None

    @property
    def buffer(self):
        return np.ctypeslib.as_array(self._cbuf)
Run Code Online (Sandbox Code Playgroud)

除了避免复制,这也意味着我可以使用numpy的索引和赋值语法,并将其直接传递给其他numpy函数:

wrap = MyWrapper()
buf = wrap.buffer       # buf is now a writeable view of a C-allocated buffer

buf[:] = np.arange(10)  # this is pretty cool!
buf[::2] += 10 …
Run Code Online (Sandbox Code Playgroud)

c python ctypes numpy dangling-pointer

26
推荐指数
3
解决办法
2243
查看次数

检测悬空引用临时

Clang 3.9非常重用临时使用的内存.

此代码是UB(简化代码):

template <class T>
class my_optional
{
public:
    bool has{ false };
    T value;

    const T& get_or_default(const T& def)
    {
        return has ? value : def;
    }
};

void use(const std::string& s)
{
    // ...
}

int main()
{
    my_optional<std::string> m;
    // ...
    const std::string& s = m.get_or_default("default value");
    use(s); // s is dangling if default returned
}
Run Code Online (Sandbox Code Playgroud)

我们有大量类似上面的代码(my_optional只是一个简单的例子来说明它).

因为UB所有的clang编译器从3.9开始重用这个内存,而且它是合法的行为.

问题是:如何在编译时检测这种悬空引用,或者在运行时检测清理程序?没有clang消毒剂可以检测到它们.

UPD.请不要回答:"使用std::optional".仔细阅读:问题不是关于它.
UPD2.请不要回答:"你的代码设计很糟糕".仔细阅读:问题不是代码设计.

c++ undefined-behavior c++11 clang++ dangling-pointer

20
推荐指数
1
解决办法
1781
查看次数

为什么std :: string_view在三元表达式中创建悬空视图?

考虑std::string_view从返回a 的方法const std::string&或从空字符串返回的方法。令我惊讶的是,以这种方式编写方法会导致悬空的字符串视图:

const std::string& otherMethod();

std::string_view myMethod(bool bla) {
    return bla ? otherMethod() : ""; // Dangling view!
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/1Hu_p2

似乎编译器首先将std::string结果的临时副本otherMethod()放在堆栈上,然后返回此临时副本的视图,而不是仅返回引用的视图。首先,我想到了一个comipler错误,但是G ++和clang都这样做。

修复很容易:将其包装otherMethod为一个显式结构即可string_view解决此问题:

std::string_view myMethod(bool bla) {
    return bla ? std::string_view(otherMethod()) : ""; // Works as intended!
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/Q-sEkr

为什么会这样呢?为什么原始代码会在没有警告的情况下创建隐式副本?

c++ language-lawyer dangling-pointer string-view c++17

19
推荐指数
1
解决办法
639
查看次数

为什么unique_ptr :: operator*()没有安全的替代方案?

std::vector将成员函数at()作为安全替代operator[],以便应用绑定检查并且不会创建悬空引用:

void foo(std::vector<int> const&x)
{
  const auto&a=x[0];     // What if x.empty()? Undefined behavior!
  const auto&a=x.at(0);  // Throws exception if x.empty().
}
Run Code Online (Sandbox Code Playgroud)

但是,std::unique_ptr缺少相应的功能:

void foo(std::unique_ptr<int> const&x)
{
  const auto&a=*x;       // What if bool(x)==false? Undefined behavior!
}
Run Code Online (Sandbox Code Playgroud)

如果std::unique_ptr有这样一个安全的替代方案,那就好了,说成员ref()(和cref())永远不会返回一个悬空引用,而是抛出异常.可能的实施:

template<typename T>
typename add_lvalue_reference<T>::type
unique_ptr<T>::ref() const noexcept(false)
{
  if(bool(*this)==false)
    throw run_time_error("trying to de-refrence null unique_ptr");
  return this->operator*();
}
Run Code Online (Sandbox Code Playgroud)

这个标准没有提供这种东西有什么好的理由吗?

c++ unique-ptr dereference c++11 dangling-pointer

17
推荐指数
2
解决办法
1890
查看次数

这个构造函数初始值设定项是否会导致悬空引用?

我正在学习Stanley B. Lippman的C++ Primer第4版.在第12.4.1节中,当作者讨论构造函数初始值设定项时,他给出了这个例子:

class ConstRef {
  public:
    ConstRef(int ii);
  private:
    int i;
    const int ci;
    int &ri;
};
// OK: explicitly initialize reference and const members.
ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii) { }
Run Code Online (Sandbox Code Playgroud)

我怀疑这可能导致悬挂引用ri指向ii,这是暂时的.我对吗?

c++ reference dangling-pointer

15
推荐指数
1
解决办法
942
查看次数