使用strcpy()和复制C中char *的地址之间的区别

我有两个动态分配的数组。 C

char **a = (char**)malloc(sizeof(char*) * 5)); char **b = (char**)malloc(sizeof(char*) * 5)); for (int i = 0; i < 7, i++) { a[i] = (char*)malloc(sizeof(char)*7); b[i] = (char*)malloc(sizeof(char)*7); } 

如果a[0]"hello\0"并且我想将a[0]复制到b[0]strcpy和指针赋值是否相同? 例如:

  1. strcpy(b[0], a[0])
  2. b[0] = a[0]

这些都会做同样的事吗?

。 两者都不一样。 在这种情况下, strcpy(b[0], a[0])是将a[0]指向的字符串复制到b[0]正确方法。

b[0] = a[0] ,分配给b[0]内存将丢失并且将导致内存泄漏。 现在释放a[0]b[0]将调用未定义的行为 。 这是因为它们都指向相同的内存位置,并且两次释放相同的内存。


注意:应该注意的是,正如Matt McNabb在他的评论中指出的那样, 内存泄漏不会调用未定义的行为 。

理解这种情况下的[0]和b [0]本身就是数组(或指向字符数组的指针,更准确)

strcpy()将遍历a [0]指向的字符数组的每个单独元素。 虽然赋值b[0] = a[0]只会使b [0]指向[0]所指向的位置,导致内存泄漏(b [0]指向的内存不能free ‘d)。

使用像这样的简单图形可视化事态

  +---+ --> +------+ +---+---+---+---+---+----+ | a | | a[0] | ------> |'H'|'E'|'L'|'L'|'O'|'\0'| +---+ +------+ +---+---+---+---+---+----+ | a[1] | +------+ | ... | +------+ | a[n] | +------+ 

它们是不同的。 在strcpy()情况下,您正在复制字符,在赋值情况下,您将指针调整为指向同一个数组。

  a[0] -> allocated memory containing "hello" b[0] -> allocated memory not yet initialised 

在b [0] = a [0]之后

两者现在指向相同的记忆

  a[0] -> allocated memeory containing "hello" b[0] ---^ 

更糟糕的是现在没有任何东西指向b [0]

  allocated memory not yet initialised 

所以你永远不能释放它; 内存泄漏。

在这种特殊情况下,它们并不等同。 如果要将[0]分配给b [0],则会有内存泄漏,或者在删除arrays时可以删除相同的内存两次。

所以正确的方法是使用strcpy函数。

考虑到你的例子中有一个拼写错误。 代替

 for (int i = 0; i < 7, i++) { a[i] = (char*)malloc(sizeof(char)*7); b[i] = (char*)malloc(sizeof(char)*7); } 

应该有

 for (int i = 0; i < 5, i++) { a[i] = (char*)malloc(sizeof(char)*7); b[i] = (char*)malloc(sizeof(char)*7); } 

但是,有些情况下使用指针赋值要简单得多。 考虑交换两行“相同”动态分配数组的任务。 例如,假设我们要交换a[0]a[4] 。 我们可以使用strcpy以下面的方式完成任务

 char *tmp = malloc( 7 * sizeof( char ) ); strcpy( tmp, a[0] ); strcpy( a[0], a[4] ); strcpy( a[4[, tmp ); free( tmp ); 

但是,只交换指针会更简单:)

 char *tmp = a[0]; a[0] = a[4]; a[4] = tmp; 

没有任何需要另外分配内存然后释放它。:)