我有一个 char ** 数组,它有 3 个指针
不,你没有。您有一个包含三个值的数组。这些值恰好是指针。数组没有指针。
假设您为此数组(指向 char 的指针)分配内存:
char **array = malloc( 3 * sizeof(char*)); // 3 values in the array
然后为每个字符串分配内存:
array[0] = malloc(4 * sizeof(char) ); // 3 + 1 null terminator
array[1] = malloc(4 * sizeof(char) );
array[2] = 0;
最后,您为字符串本身设置值:
strcpy( array[0], "abc" );
strcpy( array[1], "def" );
现在你想制作一个副本。实际上是深拷贝,因为您不仅为新数组(指向 char 的指针)分配内存,而且还为新字符串分配内存。您执行完全相同的分配:
char **array2 = malloc( 3 * sizeof(char*));
array2[0] = malloc(4 * sizeof(char) );
array2[1] = malloc(4 * sizeof(char) );
array2[2] = 0;
现在你复制实际的字符串:
strcpy( array2[0], array[0] );
strcpy( array2[1], array[1] );
如果您的代码与上述代码不同,请使用更多详细信息编辑您的问题。
棘手的部分是让array[0] 保存array2[0] 中的地址(对于array[1] 和array2[1] 相同)。问题来自这样一个事实,即您分配的内存malloc
需要通过free
.
所以你不能只做
array[0] = array2[0];
因为您丢失了对分配的第一个字符串的所有引用。那个内存泄露了。
而是这样做:
free(array[0]);
array[0] = array2[0];
这将释放用于第一个字符串的内存并复制副本的地址。
现在您在两个变量中有相同的指针(值)。这也很棘手,因为(当您不再需要它时)您仍然需要释放为副本分配的内存:
free(array2[0])
棘手的部分是它array[0]
现在拥有一个指向已释放内存的指针,该指针无法使用。使用它会导致错误。
最好不要有多个变量(在同一范围内)持有相同的指向已分配内存的指针。这可能使推断指针的有效性变得困难。