如何在C ++中深层复制char *数组

时间:2017-11-01 07:39:31

标签: c++ arrays char deep-copy

我想执行char **的深层副本,但我不知道如何分配内存/复制此数据类型。这适用于包含char **的类中的复制构造函数。例如,假设我有这段代码:

char ** arr1 = new char*[20];
arr1[0] = (char*)"This is index 1";
arr1[1] = (char*)"This is index 2";
char ** arr2;

如何将arr1的内容深层复制到arr2中?任何帮助表示赞赏!

4 个答案:

答案 0 :(得分:3)

  

这是编程任务,老师想要所有的字符串   存储为char *,...

您可以告诉您的老师std::string将字符串存储为char*。如果他仍然不喜欢你使用std::string,你应该编写自己的包装器,因为使用裸char*是你在编写C时所做的,而不是在C ++中。你应该写一个:

struct my_string {
    char* data;
    ... constructor, operator[], etc...
};

你基本上不需要编写比你已经编写的更多的代码,但你应该把它放在正确的位置(即隐藏在一个漂亮的界面后面)。当你考虑......时,你会立即看到它的好处。

  

...所以字符串数组必须存储为char *。

数组

没有。字符串数组是std::array<my_string>(如果它应该是动态的,则为std::vector<my_string>)。如果你的老师坚持不使用std::vector,那么你应该像你刚才为矢量的字符串做的那样(即在一个地方封装所有脏指针和内存的东西)。

答案 1 :(得分:1)

这似乎更像是一个C问题,但这是一个例子:

char **AllocateAndDeepCopy(char **arr1, int arr1size) 
{
    unsigned int    i;
    char            **arr2;

    /* Allocate string array */
    arr2 = new char*[arr1size];

    /* Iterate array elements */
    for (i=0; i<arr1size; i++) {
        /* Allocate string */
        arr2[i] = new char[strlen(arr1[i])+1];

        /* Copy contents */
        strcpy(arr2[i], arr1[i]);
    }   

    return arr2;
}

稍后您必须以这种方式释放arr2

void DeallocateArr2(char **arr2, int size) 
{
    for (int i=0; i<size; i++) {
        delete arr2[i];     
    }

    delete arr2;
}

答案 2 :(得分:0)

只需查看http://en.cppreference.com/w/cpp/algorithm/copy,即可制作深层副本     * d_first ++ = * first ++;

答案 3 :(得分:0)

我只能摇头抱怨C ++教育的抱歉状态。我们有一种方式去那里。但是,由于这显然是一个给定的,你能做的最好的是什么?

复制C风格的数据结构,就像你在复制时知道两件事一样。两者都不是由C风格的数组本身提供的,所以你必须明确地跟踪它们。

  • arr1容量: 20 。如果那不是编译时常量,你必须存储并传递它。由于您希望实现一个复制ctor,这意味着将容量存储在对象的非静态成员变量中。
  • arr1 中使用的索引数量: 2 。与上述相同。或者,确保将所有未使用的索引设置为nullptr

现在您可以分配正确大小的arr2,然后分配+ memcpy所有使用的索引。

然而,无论,您的程序都会火上浇油,因为arr1arr2不能被视为相同,即使它们看起来相同。使用的arr1索引永远不能是delete d因为它们包含指向字符文字的指针:它们从不new d并且只存在于只读内存中。另一方面,您绝对必须delete arr2的索引,因为他们 new d。

如果这项作业真的需要对这种野蛮的无视,我会更进一步。我将介绍另一个成员变量,一个布尔数组,它跟踪char数组的哪些索引指向char文字,哪些是动态分配的。在复制过程中,您现在拥有memcpy所需的所有必要信息或只是设置指针。疯?当然,但整个任务是,这样的疯狂至少可见,而不是隐藏在一个无辜的C风格演员背后。顺便说一句:那些应该const_cast<char*>来清楚说明发生了什么。