【问题标题】:I need fastest way to clone vector< char * > in C++我需要在 C++ 中克隆向量< char * > 的最快方法
【发布时间】:2023-03-25 03:39:01
【问题描述】:

我尝试过这种方式..但它太慢了,

我需要克隆包含数百万个字符 * 的向量。`

vector <char * > A ; // contains more than 1 million item.
vector <char * > B;



char * buffer=NULL;
for(long i = 0; i < A.size(); i++)
{
        buffer = (char*) malloc (strlen(A[i])+1);
        strcpy(buffer,A[i]);
        buffer[strlen(A[i])+1]='\0';
        B.push_back(buffer);
}

有比这更快的克隆向量的方法吗??

它很慢.. 如果我使用

vector <char * > B=A; // when free A .. I have double free Exception (run time error ) ..

谢谢。

【问题讨论】:

  • 是的,太慢了。你对此无能为力。也许改进你的算法,这样你就不需要复制它了。
  • 您的第二个示例不复制字符串,而是保留原始指针,因此出现双重释放异常。你的第一种形式是正确的。
  • @H2CO3,+1,您可能还想使用字符串,这样您就可以避免使用 strcpy() 和 malloc。
  • @IbrahimAsad,考虑避免这种情况的替代方法:使用 std::shared_ptr<:vector>>,调整您的算法以一一使用处理字符串,或参考 -自己计算 char* (然后复制只会复制指针值)。
  • 重要的问题是:您需要只读副本还是要克隆数据本身?

标签: c++ vector malloc free


【解决方案1】:

假设您更喜欢更快的算法而不是节省空间,您可以尝试自己实现一种称为引用计数 / copy-on-write 的技术。除非绝对必要(例如,如果执行对字符串的编辑),否则避免复制字符串的想法。

Scott Meyer 的“更有效的 C++”一书中描述了该主题(此处无法解释)(使用旧实现)。具体来说,第 30 项(引用计数)将深入探讨相关字符串的构造。它的全部目的是增强像你这样的算法:

引用计数的第二个动机是简单的常识。如果许多对象具有相同的值,那么多次存储该值是愚蠢的。相反,最好让所有具有该值的对象共享其表示。这样做不仅可以节省内存,还可以让程序运行得更快,因为不需要构造和销毁相同对象值的冗余副本。

对于实现,您可以轻松地使用std::shared_ptr(C++11 起)或boost::shared_ptr(C++11 之前),它们提供了对字符串进行引用计数所需的大部分机制:

std::shared_ptr<char> string(new char[n], [](int *ptr) { delete[] ptr; });

如果您不需要修改字符串(但我非常怀疑,对吗?),您应该将它们声明为 const char* 并避免重新分配。

【讨论】:

  • C++11 中不允许写入时复制字符串,以前很少见。
  • @Jefffrey 21.4.1 '[复制构造字符串的数据]指向分配的数组副本的第一个元素,该数组的第一个元素由[源]指向 str.data( )'
  • Reference。哦,为什么自己写这样的东西不是一个好主意呢?因为标准库有通用工具可以为您处理这个问题,最简单的形式是智能指针或vector&lt;char&gt;(但由于内存限制,最后一个似乎是不可能的)
  • 线程安全的 Copy-on-write stackoverflow.com/questions/4309548/… 可能在这里有用
  • @Jefffrey 不,放松,这是对当前形式的问题的完美答案。
【解决方案2】:

你可以改变

for(long i = 0; i < A.size(); i++)
{
        buffer = (char*) malloc (strlen(A[i])+1);
        strcpy(buffer,A[i]);
        buffer[strlen(A[i])+1]='\0';
        B.push_back(buffer);
}

B.resize(A.size());
for(long i = 0; i < B.size(); ++i)
{
        B.at(i) = new char[ strlen(A.at(i)) ];
        for(int j=0; B.at(i)[j] = A.at(i)[j]; ++j);
}

更小的代码可能会加快速度。您也可以尝试调整编译器的优化设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多