我想执行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中?任何帮助表示赞赏!
答案 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所有使用的索引。
然而,无论,您的程序都会火上浇油,因为arr1
和arr2
不能被视为相同,即使它们看起来相同。使用的arr1
索引永远不能是delete
d因为它们包含指向字符文字的指针:它们从不new
d并且只存在于只读内存中。另一方面,您绝对必须delete
arr2
的索引,因为他们 new
d。
如果这项作业真的需要对这种野蛮的无视,我会更进一步。我将介绍另一个成员变量,一个布尔数组,它跟踪char数组的哪些索引指向char文字,哪些是动态分配的。在复制过程中,您现在拥有memcpy所需的所有必要信息或只是设置指针。疯?当然,但整个任务是,这样的疯狂至少可见,而不是隐藏在一个无辜的C风格演员背后。顺便说一句:那些应该const_cast<char*>
来清楚说明发生了什么。