简体   繁体   English

如何使用 memcpy 复制 char**

[英]How to copy a char** using memcpy

I have two char ** variables:我有两个 char ** 变量:

char ** a;
char ** b;

with a containing a bunch of char arrays and so does b , after reallocing the memory of a , I wanted to append it with b char arrays, as it showen below: with a containing a bunch of char arrays and so does b , after reallocing the memory of a , I wanted to append it with b char arrays, as it showen below:

memcpy(a + oldSizeOfA, b, sizeOfB);

I'm expecting that all of the char arrays in b will be in a , what am I doing wrong?我期待b中的所有 char arrays 都在a中,我做错了什么?

I tried to simplify my code to this:我试图将我的代码简化为:

char ** a = (char **)malloc(5*sizeof(char*));
char ** b = (char **)malloc(10*sizeof(char*));

for (i = 0; i < 5; i++) 
{
    b[i] = (char *)malloc(4);
    strcpy(b,"tes");

    a[i] = (char *)malloc(4);
    strcpy(a,"tes");
}

memcpy(&a + 5, &b, 5);

If you want to copy five elements from the array b to the five positions starting at index 5 in array a, you don't want:如果要将数组 b 中的五个元素复制到数组 a 中从索引 5 开始的五个位置,则不需要:

memcpy(&a + 5, &b, 5);

It should be它应该是

memcpy(a + 5, b, 5 * sizeof(*b)); // See Note below

That's independent of the type of what a and b point to.这与ab指向的类型无关。

But note that if a and b point to pointers, then only the pointers are being copied.但请注意,如果ab指向指针,则只有指针被复制。 So if a and b are arrays of character strings -- char** -- then you'll end up with a[5] being the same pointer as b[0] .因此,如果ab是字符串的 arrays -- char** -- 那么你最终会得到a[5]b[0]相同的指针。 That might be fine, but it could also be a problem.这可能很好,但也可能是一个问题。 For example, if you modify some character in b[0] , the string pointed to be a[5] (which is the same string) will also be changed.例如,如果您修改b[0]中的某个字符,则指向a[5]的字符串(即同一个字符串)也将被更改。 And, critically, if you free(b[0]) , then a[5] is no longer a valid pointer, so you cannot refer to it or free it.而且,至关重要的是,如果你free(b[0]) ,那么a[5]不再是一个有效的指针,所以你不能引用它或free它。

Not copying the character strings can save you a lot of memory, but the memory sharing comes at a huge price in bookkeeping.不复制字符串可以为您节省大量的 memory,但是 memory 共享在簿记中付出了巨大的代价。 It's often simpler to make new strings, which means that you need to use something like strdup (or you could write out the malloc and the strcpy , but strdup is less bug-prone).制作新字符串通常更简单,这意味着您需要使用类似strdup的东西(或者您可以写出mallocstrcpy ,但strdup不太容易出错)。


Note笔记

a and b are variables with addresses. ab是带地址的变量。 &a and &b are the addresses of the variables. &a&b是变量的地址。 Since a is a scalar variable, &a + 5 is undefined behaviour.由于a是一个标量变量, &a + 5是未定义的行为。 It points at somewhere else in your function's local stack frame (if the stack frame is big enough), which means to some other local variable.它指向函数的本地堆栈帧中的其他位置(如果堆栈帧足够大),这意味着其他一些局部变量。 But you don't know which variable, and you don't have any right to describe it that way, even if you knew which one it was.但是你不知道是哪个变量,而且你没有任何权利这样描述它,即使你知道它是哪一个。

What you're interested in is the address of the sixth slot in the array a points at, which is a + 5 (thanks to C pointer arithmetic) or &a[5] , which many people would say is clearer.您感兴趣的是数组a指向的第六个插槽的地址,即a + 5 (感谢 C 指针算法)或&a[5] ,很多人会说这更清楚。

Also, like malloc , memcpy counts in bytes, not elements (since it doesn't know the element size).此外,就像malloc一样, memcpy以字节为单位,而不是元素(因为它不知道元素大小)。 So a count of 5 means "5 bytes", which you'll find is a lot less than five pointers.所以计数 5 意味着“5 个字节”,你会发现它比五个指针少得多。 (Indeed, it's probably less than one pointer.) (实际上,它可能少于一个指针。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM