[英]Difference between using strcpy() and copying the address of a the char* in C
我有兩個動態分配的數組。 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]
兩者都會做同樣的事情嗎?
不行 兩者都不一樣。 在這種情況下, strcpy(b[0], a[0])
是將a[0]
指向的字符串復制到b[0]
正確方法。
如果b[0] = a[0]
,分配給b[0]
內存將丟失,並且將導致內存泄漏。 現在釋放a[0]
和b[0]
都將調用未定義的行為 。 這是因為它們兩個都指向相同的內存位置,並且兩次釋放相同的已分配內存。
注意:應該注意的是,正如Matt McNabb在其評論中指出的那樣, 內存泄漏不會調用未定義的行為 。
了解在這種情況下,a [0]和b [0]本身就是數組(或更精確地說,是指向字符數組的指針)
strcpy()
將遍歷a [0]指向的字符數組的每個單獨元素。 雖然賦值b[0] = a[0]
只會使b [0]指向a [0]指向的位置,從而導致內存泄漏(b [0]指向的內存無法free
)。
使用這樣的簡單圖形可視化事務狀態-
+---+ --> +------+ +---+---+---+---+---+----+
| 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
所以你永遠無法釋放它; 內存泄漏。
在這種特定情況下,它們並不等效。 如果將a [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;
無需分配額外的內存,然后再釋放它。:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.