2016-11-05 67 views
0

首先,这不是duplicate。我的问题是如何用动态内存来做到这一点。这是不同的原因是因为我的delete[]挂。如何将非空字符串复制到动态内存

所以,这里是我有:

class PacketStrRet { 
    public: 
    PacketStrRet(char p_data[], int p_len) : len(p_len) { 
     data = new char[p_len]; 
     memcpy(data, p_data, p_len * sizeof(char)); 
    } 

    ~PacketStrRet() { 
     delete[] data; 
     data = nullptr; 
    } 

    char* data; 
    int len; 
}; 

是的,我知道,我的代码是不是使用的最佳实践。我会在稍后清理它。

我遇到的问题是在DTOR中。该删除是永久悬挂的。传递给CTOR的数据是而不是动态内存,所以我需要使其动态变化,所以事情不会超出范围。 p_len拥有正确的数据量,所以这里没有问题。

从我读过的,memcpy似乎是这里最有可能的罪魁祸首。那么,我该如何复制一个不以空字符结尾的字符串到动态内存中,然后还能够将其删除呢?

谢谢。

+0

这也看起来像三违反规则。 –

+0

@KerrekSB,你可以把它放入答案吗? – David

+0

看起来没问题。只要你没有奇怪的平台,或者将它添加到'new'调用中,你就可以删除memcpy中的* sizeof(char),但这应该没有什么区别。我猜这个错误是在其他地方。 – Matthias247

回答

-1

尝试使用std :: copy()。这将是这样的: std::copy(p_data, p_data + p_len, data).

+0

这与“memcpy”有什么不同,除了更多的开销? – David

+0

@David - 'std :: copy'没有“更多开销”。 –

1

问题不在于是否有没有发生任何问题,来之前甚至认为将是确定删除,只有一切。

class PacketStrRet { 
    // Use RAII 
    std::unique_ptr<char> data; // I own this data and will destroy it. 
    // now the parent class is also only movable, use shared_ptr if you can't live with that. 
    int len; 

    public: 
    PacketStrRet(
     // <RED ALERT> 
     char p_data[], int p_len // user can lie to us. 
     // </RED ALERT> 
     ) try : // function try block, se 1) 
      len(p_len), data(new char[p_len]) { 
     memcpy(data, p_data.get(), p_len * sizeof(char)); 
    } catch(const std::exception& e) { 
     std::cerr << "arg=" << arg << " failed: " << e.what() << '\n'; 
    } 

    ~PacketStrRet() { 
     // unique_ptr takes care of memory management and garbage collection. 
    } 
    // access functions 
}; 

现在您可能会犯的错误代码。

您可能已经复制了该对象,实质上使两个拥有的原始指针指向相同的数据。这会在删除时炸毁,您可以使用memory-sanitizer/valgrind来确认发生这种情况。使用智能指针为您节省麻烦,唯一的指针应该如果您试图复制,会导致编译器错误,除非您memcpy整个结构忽略复制/分配构造函数。

你可以给构造函数给出错误的len,数据和len的来源是什么? Valgrind /记忆消毒器可以为您节省。

内存损坏可能发生在一个完全不同的地方。 Valgrind /记忆消毒器可以为您节省。

如果valgrind mem-san太多,您可以尝试检查双删除,如果您在c'tor和d'tor中创建了一个计数器,并且如果它变成负数,您的错误将会消失。

在这个类中你至少缺少一个拷贝构造函数。检查3,5,7和0(零)的规则,找出你需要多少。

1)http://en.cppreference.com/w/cpp/language/function-try-block

相关问题