我有两个动态分配的数组。 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
和指针赋值是否相同?例如:
strcpy(b[0], a[0])
b[0] = a[0]
这些都会做同样的事吗?
答案 0 :(得分:3)
否即可。两者都不一样。在这种情况下,strcpy(b[0], a[0])
是将a[0]
指向的字符串复制到b[0]
的正确方法。
如果是b[0] = a[0]
,分配给b[0]
的内存将丢失,并且会导致内存泄漏。现在释放a[0]
和b[0]
将调用未定义的行为。这是因为它们都指向相同的内存位置,并且两次释放相同的内存。
注意:请注意,Matt McNabb comment指向memory leak does not invokes undefined behavior。
答案 1 :(得分:1)
理解这种情况下的[0]和b [0]本身就是数组(或指向字符数组的指针,更准确)
strcpy()
将遍历a [0]指向的字符数组的每个单独元素。
虽然赋值b[0] = a[0]
只会使b [0]指向[0]所指向的位置,导致内存泄漏(b [0]指向的内存不能是free
&#39; d)。
使用像这样的简单图形可视化事态 -
+---+ --> +------+ +---+---+---+---+---+----+
| a | | a[0] | ------> |'H'|'E'|'L'|'L'|'O'|'\0'|
+---+ +------+ +---+---+---+---+---+----+
| a[1] |
+------+
| ... |
+------+
| a[n] |
+------+
答案 2 :(得分:0)
他们是不同的。在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
所以你永远不能释放它;记忆泄漏。
答案 3 :(得分:0)
在这种特殊情况下,它们并不等同。如果要将[0]分配给b [0],则会有内存泄漏,或者在删除阵列时可以删除相同的内存两次。
所以正确的方法是使用函数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;
没有必要另外分配内存然后释放它。:)