dan*_*dan 21 c c++ arrays char multidimensional-array
我正在寻找一种将多维char数组复制到新目标的智能方法.我想复制char数组,因为我想编辑内容而不更改源数组.
我可以构建嵌套循环来手动复制每个字符,但我希望有更好的方法.
更新:
我没有2. level维度的大小.给定的只是长度(行).
代码如下所示:
char **tmp;
char **realDest;
int length = someFunctionThatFillsTmp(&tmp);
//now I want to copy tmp to realDest
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种方法,将tmp的所有内存复制到空闲内存中,并将realDest指向它.
更新2:
someFunctionThatFillsTmp()是Redis C lib credis.c中的函数credis_lrange().
在lib tmp中创建了:
rhnd->reply.multibulk.bulks = malloc(sizeof(char *)*CR_MULTIBULK_SIZE)
Run Code Online (Sandbox Code Playgroud)
更新3:
我试过用这行代码使用memcpy:
int cb = sizeof(char) * size * 8; //string inside 2. level has 8 chars
memcpy(realDest,tmp,cb);
cout << realDest[0] << endl;
prints: mystring
Run Code Online (Sandbox Code Playgroud)
但是我得到了一个:程序接收信号:EXC_BAD_ACCESS
Yac*_*oby 33
你可以用memcpy
.
如果在编译时给出多维数组大小,即mytype myarray[1][2]
,则只需要一次memcpy调用
memcpy(dest, src, sizeof (mytype) * rows * coloumns);
Run Code Online (Sandbox Code Playgroud)
如果像你指示的那样动态分配了数组,你将需要知道两个维度的大小,就像动态分配时一样,数组中使用的内存不会在连续的位置,这意味着memcpy将不得不多次使用.
给定一个2d数组,复制它的方法如下:
char** src;
char** dest;
int length = someFunctionThatFillsTmp(src);
dest = malloc(length*sizeof(char*));
for ( int i = 0; i < length; ++i ){
//width must be known (see below)
dest[i] = malloc(width);
memcpy(dest[i], src[i], width);
}
Run Code Online (Sandbox Code Playgroud)
鉴于你的问题看起来你正在处理一个字符串数组,你可以使用strlen来查找字符串的长度(它必须以null结尾).
在这种情况下,循环将成为
for ( int i = 0; i < length; ++i ){
int width = strlen(src[i]) + 1;
dest[i] = malloc(width);
memcpy(dest[i], src[i], width);
}
Run Code Online (Sandbox Code Playgroud)
当你有一个指向C中指针的指针时,你必须知道数据将如何在内存中使用和布局.现在,第一点是显而易见的,对于任何变量都是如此:如果你不知道某个变量将如何在程序中使用,那为什么呢?:-).第二点更有趣.
在最基本的级别,指针输入T
点到一个类型的对象T
.例如:
int i = 42;
int *pi = &i;
Run Code Online (Sandbox Code Playgroud)
现在,pi
指向一个int
.如果您愿意,可以使指针指向许多此类对象中的第一个:
int arr[10];
int *pa = arr;
int *pb = malloc(10 * sizeof *pb);
Run Code Online (Sandbox Code Playgroud)
pa
现在指向10个(连续)int
值的序列中的第一个,并假设malloc()
成功,pb
指向另一组10(再次,连续)int
s中的第一个.
如果您有指向指针的指针,则同样适用:
int **ppa = malloc(10 * sizeof *ppa);
Run Code Online (Sandbox Code Playgroud)
假设malloc()
成功,现在您已ppa
指向10个连续int *
值序列中的第一个.
所以,当你这样做时:
char **tmp = malloc(sizeof(char *)*CR_MULTIBULK_SIZE);
Run Code Online (Sandbox Code Playgroud)
tmp
指向char *
一系列CR_MULTIBULK_SIZE
此类对象中的第一个对象.每个上面的指针没有初始化,所以tmp[0]
对tmp[CR_MULTIBULK_SIZE-1]
所有包含垃圾.初始化它们的一种方法是对malloc()
它们:
size_t i;
for (i=0; i < CR_MULTIBULK_SIZE; ++i)
tmp[i] = malloc(...);
Run Code Online (Sandbox Code Playgroud)
在...
上面的是规模i
,我们希望日的数据.它可以是常数,也可以是变量,取决于i
月亮的相位,或随机数,或其他任何东西.要注意的要点是你在循环中有CR_MULTIBULK_SIZE
调用malloc()
,并且虽然每个malloc()
都将返回一个连续的内存块,但是在malloc()
调用之间不能保证连续性.换句话说,第二次malloc()
调用不能保证返回一个指针,该指针从前malloc()
一个数据结束的地方开始.
为了使事情更具体,我们假设CR_MULTIBULK_SIZE
是3.在图片中,您的数据可能如下所示:
+------+ +---+---+
tmp: | |--------+ +----->| a | 0 |
+------+ | | +---+---+
| |
| |
| +------+------+------+
+-------->| 0 | 1 | 2 |
+------+------+------+
| |
| | +---+---+---+---+---+
| +--->| t | e | s | t | 0 |
+------+ +---+---+---+---+---+
|
|
| +---+---+---+
+--->| h | i | 0 |
+---+---+---+
Run Code Online (Sandbox Code Playgroud)
tmp
指向3个char *
值的连续块.第一个指针指向tmp[0]
一个由3个char
值组成的连续块.类似地, tmp[1]
和tmp[2]
指向5和2 char
分别秒.但内存指向tmp[0]
到tmp[2]
是不连续的整体.
由于memcpy()
复制连续的内存,你想要做的事情不能由一个人完成memcpy()
.此外,您需要知道每个tmp[i]
分配方式.所以,一般来说,你想做的事情需要一个循环:
char **realDest = malloc(CR_MULTIBULK_SIZE * sizeof *realDest);
/* assume malloc succeeded */
size_t i;
for (i=0; i < CR_MULTIBULK_SIZE; ++i) {
realDest[i] = malloc(size * sizeof *realDest[i]);
/* again, no error checking */
memcpy(realDest[i], tmp[i], size);
}
Run Code Online (Sandbox Code Playgroud)
如上所述,您可以memcpy()
在循环内部调用,因此您不需要在代码中使用嵌套循环.(最有可能memcpy()
是通过循环实现的,因此效果就好像你有嵌套循环一样.)
现在,如果你有像这样的代码:
char *s = malloc(size * CR_MULTIBULK_SIZE * sizeof *s);
size_t i;
for (i=0; i < CR_MULTIBULK_SIZE; ++i)
tmp[i] = s + i*CR_MULTIBULK_SIZE;
Run Code Online (Sandbox Code Playgroud)
即,您为一个malloc()
调用中的所有指针分配了连续空间,然后您可以在代码中没有循环的情况下复制所有数据:
size_t i;
char **realDest = malloc(CR_MULTIBULK_SIZE * sizeof *realDest);
*realDest = malloc(size * CR_MULTIBULK_SIZE * sizeof **realDest);
memcpy(*realDest, tmp[0], size*CR_MULTIBULK_SIZE);
/* Now set realDest[1]...realDest[CR_MULTIBULK_SIZE-1] to "proper" values */
for (i=1; i < CR_MULTIBULK_SIZE; ++i)
realDest[i] = realDest[0] + i * CR_MULTIBULK_SIZE;
Run Code Online (Sandbox Code Playgroud)
从上面可以看出,简单的答案是,如果你有多个malloc()
为内存分配内存tmp[i]
,那么你需要一个循环来复制所有数据.
您只需计算数组的整体大小,然后使用memcpy复制它.
int cb = sizeof(char) * rows * columns;
memcpy (toArray, fromArray, cb);
Run Code Online (Sandbox Code Playgroud)
编辑:问题中的新信息表明数组的行数和列数未知,并且数组可能是不规则的,因此memcpy可能不是解决方案.