我想使用智能指针而不是原始指针.如何相应地转换此功能?
Node * List::next(const Node * n) const {
return n->next;
}
Run Code Online (Sandbox Code Playgroud) 我已经实现了一个智能指针类,当我尝试编译时,它停在一个特定的行上,我得到这个消息:test.exe中0x00418c38处的未处理异常:0xC0000005:访问冲突读取位置0xfffffffc.
我的代码是:
template <class T>
class SmartPointer
{
private:
T* ptr;
int* mone;
public:
SmartPointer() : ptr(0), mone(0) //default constructor
{
int* mone = new int (1);
}
SmartPointer(T* ptr2) : ptr(ptr2), mone(0)
{
int* mone = new int (1);
}
SmartPointer<T>& operator= (const SmartPointer& second) //assignment operator
{
if (this!= &second)
{
if (*mone==1)
{
delete ptr;
delete mone;
}
ptr = second.ptr;
mone = second.mone;
*mone++;
}
return *this;
}
~SmartPointer() // Destructor
{
*mone--;
if (*mone==0) …Run Code Online (Sandbox Code Playgroud) 知道这些容器已经管理了内存,在STL容器(向量,地图等)中使用智能指针有什么好处?
例:
std::vector<std::unique_ptr<int>>
Run Code Online (Sandbox Code Playgroud)
代替
std::vector<int*>
Run Code Online (Sandbox Code Playgroud) 据我的理解,建议std::observer_ptr有关,std::unique_ptr如以同样的方式std::weak_ptr有关std::shared_ptr.
那么为什么std::observer_ptr<W>界面,根据提案N4282,允许从W*指针构造?
这意味着包含W*as成员的实现,可能类似于本答案中给出的伪实现,其最简单地提出
template<typename T>
using observer_ptr = T*;
Run Code Online (Sandbox Code Playgroud)
因此,这似乎超出了有效性检查,如下所示:
std::unique_ptr<W> u = std::make_unique<W>();
std::observer_ptr<W> o(uptr.get());
uptr.reset();
if(o)
{
//u is already nullptr, but o doesn't know
o->foo(); //invalid dereferentation
}
Run Code Online (Sandbox Code Playgroud)
相反,我希望只允许执行以下操作:
std::unique_ptr<W> u = std::make_unique<W>();
std::observer_ptr<W> o(uptr);
uptr.reset();
if(o)
{
//execution doesn't get here, o is nullptr
}
Run Code Online (Sandbox Code Playgroud)
这相当于std::weak_ptr通过锁定它可以做到的事情,并且imo observer_ptr可以提供超过非拥有原始指针的核心优势.
那么,为什么不执行呢?
我决定并行化我写的一个巨大的程序,最后我遇到了新的C++ 11智能指针.
我有一个例程,应该执行多次(通常超过1000次),这有点贵.它是在一个简单的for循环中运行的,我所做的是在一个方法中安装这个for循环,该方法将由一些工作线程运行.
是这样做的,做了一些参数包裹std::shared_ptr,关注竞争条件,一切似乎都很好.
但现在,有些时候,进程将被中止,我会收到以下错误之一:
进程以退出代码139结束(由信号11中断:SIGSEGV)
要么
malloc.c:2395:sysmalloc:断言`(old_top == initial_top(av)&& old_size == 0)|| ((unsigned long)(old_size)> = MINSIZE && prev_inuse(old_top)&&((unsigned long)old_end&(pagesize - 1))== 0)'失败.
并行for正在进行时发生所有这些错误; 不是之前,不是一开始,不是最后,而是介于两者之间,这让我闻起来像一个未被覆盖的竞争条件.
该程序是巨大的,但我创建了一个能够重现问题的缩影:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <thread>
#include <set>
#include <memory>
#include <atomic>
namespace std {
template <>
struct hash<std::multiset<unsigned long>>
{
std::size_t operator()(const std::multiset<unsigned long>& k) const
{
std::size_t r = 0;
bool shift = false;
for (auto&& it : k) {
r = (r >> !shift) ^ (std::hash<unsigned long>()(it) …Run Code Online (Sandbox Code Playgroud) 免责声明:我知道不应该使用unique_ptr,但为了便于理解,我想知道这里发生了什么.谢谢!
考虑这个功能:
void foo(int* a) {
unique_ptr<int> pointer_in_function(a);
}
Run Code Online (Sandbox Code Playgroud)
而这个主要功能:
int main(void) {
int* myInt = new int(5);
unique_ptr<int> pointer_in_main(myInt);
foo(myInt);
cout << *pointer_in_main << endl;
cout << *pointer_in_main << endl;
cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我一直从第一个cout得到正确的答案.第二个是未定义的.该程序有时会在退出时出现严重错误而崩溃,但并非总是如此.
我不明白为什么第一个cout一致地给出了正确的答案.当pointer_in_function超出范围时,myInt指向的整数是否应该被删除?谢谢您的帮助!
编辑:顺便说一句,为了确保,我在假设调用foo应该删除我的整数是正确的,因为pointer_in_function超出了范围?
这是未定义的行为吗?如果指针指向无处,它如何删除分配的资源?
// Example program
#include <iostream>
#include <memory>
class A {
public:
A() {std::cout << "ctor"<<std::endl;};
~A(){std::cout << "dtor"<<std::endl;};
};
int main()
{
std::unique_ptr<A> ptr(new A);
ptr = nullptr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
ctor
dtor
Run Code Online (Sandbox Code Playgroud)
也许它是故意用这种方式来解决某种问题的?
我无法std::vector<std::unique_ptr<..>>从函数中移动:MSVC抱怨(C2280)关于尝试引用已删除的函数.
这怎么样?
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
class foo {
public:
int i;
};
vector<unique_ptr<foo>> test() {
vector<unique_ptr<foo>> ret{};
auto f = make_unique<foo>();
f->i = 1;
ret.push_back(move(f));
return move(ret);
}
int main(int argc, char** argv) {
auto t = test();
for (auto j : t) {
// fails here: --^
cout << j->i << endl;
}
getchar();
}
Run Code Online (Sandbox Code Playgroud)
完整的错误消息显示:
'std :: unique_ptr> :: unique_ptr(const std :: unique_ptr <_Ty,std :: default_delete <_Ty >>&)':尝试引用已删除的函数
我正在尝试在person类中编写单例模式,这使我能够为该类创建一个实例,并且我可以在我的程序中的任何位置使用它.
以下是班级:
// The declaration
class Person {
static unique_ptr<Person> instance;
Person() = default;
Person(Person&) = delete;
Person& operator=(const Person&) = delete;
~Person() = default;
public:
static unique_ptr<Person> getInstance();
};
// The implementation
unique_ptr<Person> instance = NULL;
unique_ptr<Person> Person::getInstance() {
if (instance == NULL) {
instance = unique_ptr<Person>(new Person());
}
return instance;
}
Run Code Online (Sandbox Code Playgroud)
但它给我这个错误的问题: Error C2280 'std::unique_ptr<Person,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
不幸的是,我不明白这个问题,我不知道如何解决?
使用原始指针,我可以创建一个指针和push_back地址的向量,如下所示:
Entity objEntity;
std::vector<Entity*> Entities;
Entities.push_back(&objEntity);
Run Code Online (Sandbox Code Playgroud)
如果我改为使用共享指针向量:
std::vector<std::shared_ptr<Entity>> Entities;
Run Code Online (Sandbox Code Playgroud)
...如何推送地址?
据我所知,std :: shared_ptr :: reset用于将现有对象的地址分配给智能指针.我是否需要先创建一个临时指针,调用reset,然后再调用push_back?
std::shared_ptr<Entity> temp;
temp.reset(&objEntity);
Entities.push_back(temp);
Run Code Online (Sandbox Code Playgroud) c++ ×10
smart-pointers ×10
c++11 ×2
c++17 ×1
pointers ×1
shared-ptr ×1
singleton ×1
stdvector ×1
stl ×1
unique-ptr ×1