[英]How to deep copy an array of char * in C++
我想执行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中? 任何帮助表示赞赏!
这是用于编程作业,老师希望所有字符串都存储为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
,那么您应该像对vector的字符串一样进行操作(即将所有脏指针和内存内容封装在一个地方)。
这似乎更像一个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;
}
只需看一下http://en.cppreference.com/w/cpp/algorithm/copy ,深层副本就由* d_first ++ = * first ++;创建。
对于C ++教育的遗憾状态,我只能摇头。 我们有很长的路要走。 但是,既然这显然是给定的,那么您能做的最好的事情是什么?
要复制这样的C样式数据结构,您在复制时要了解两件事。 两者都不是由C样式数组固有提供的,因此您必须明确地跟踪它们。
arr1
的容量 : 20 。 如果这不是编译时间常数,则必须将其存储并传递。 由于要实现一个复制ctor,这意味着将容量存储在对象的非静态成员变量中。 arr1
中使用的索引arr1
: 2 。 同上。 或者,确保所有未使用的索引都设置为nullptr
。 现在,您可以分配正确大小的arr2
,然后分配+ memcpy所有使用的索引。
但是, 无论如何 , 您的程序都会 arr1
,因为即使它们看起来相同,也无法将arr1
和arr2
视为相同。 使用过的arr1
索引永远不能delete
d,因为它们包含指向字符文字的指针:它们绝不是new
d,并且位于只读内存中。 另一方面,您绝对必须delete
arr2
的索引,因为它们是 new
d。
如果作业确实需要这种对const的残酷无视,那么我会更进一步。 我将介绍另一个成员变量,一个布尔数组,该数组跟踪char数组的哪些索引指向char文字,以及哪些是动态分配的。 复制期间,您现在拥有了所有必要的信息以进行memcpy或仅设置指针。 疯? 绝对可以,但是整个任务都是这样,这样,疯狂就至少可见,而不是隐藏在无辜的C风格演员之后。 顺便说一句:那些应该是const_cast<char*>
,以明确发生了什么事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.