[英]difference between creating an array “normally” and with malloc
我正在搞亂指向要學習的函數指針的C指針。 我創建了一個字符串數組,並希望使用指向指針的函數在函數foo
更改它。 我然后打印它,只是為了看。
問題是:如果我“正常”創建它: char array[] = "yeah"
,代碼不起作用,我在控制台上看到一堆奇怪的字符。 但是,如果我用malloc
創建它,它的工作原理。 我真的很想了解其中的差異。
這有效:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void foo(char **ptr);
int main(int argc, char *argv[]) {
char *array = malloc(sizeof("yeah")); //I need to malloc here, or it doesn't work. Why ?
strcpy(array, "yeah");
printf("array before : %s \n", array);
char *ptr = array;
char **pt = &ptr;
foo(&array);
printf("array after : %s \n", array);
free(array);
}
void foo(char **ptr) {
char *truc = malloc(sizeof(char) * 20); //I need to malloc here, else it doesn't work. Why ?
strcpy(truc, "then");
*ptr = truc;
}
但這不,它在控制台上打印令人討厭的字符:
void foo(char **ptr);
int main(int argc, char *argv[]) {
char array[] = "yeah"; //created "normally"
printf("array before : %s \n", array);
char *ptr = array;
char **pt = &ptr;
foo(&array);
printf("array after : %s \n", array);
free(array);
}
void foo(char **ptr) {
char truc = "then";
*ptr = truc;
}
有什么區別:
char array[] = "yeah";
和
char *array = malloc(sizeof("yeah");
strcpy(array, "yeah");
首先要注意的是:代碼: char array[] = "yeah";
將工作。
注意:如果執行此操作,則不會調用free(array)
因為它不是指向動態分配的內存的指針,並且不需要動態返回到堆。 它存在於堆棧中。 繼續閱讀......
但是函數foo()
在這里是個問題。 當調用foo()
,字符串truc
(也可以聲明為char truc[] = "then";
)存在於堆棧幀中,這是程序存儲器的一部分,只有在foo()
返回時才存在。 如果將array
更改為指向該堆棧幀內的內存,該函數返回時會發生什么? 堆棧幀變得不確定,你只能指向垃圾內存。
如果要更改array
字符串的內容,可以確保緩沖區足夠長,並且foo()
可以strcpy(array, "then")
。 所以,你不是要改變指針本身,只是它指向的內存。 這不是我稱之為好的軟件設計,但為了舉個例子,它對你有用。 像這樣:
void foo(char * ptr)
{
strcpy(ptr, "then");
}
main()
malloc()
main()
呢? 當你在main()
沒有 malloc()
時, array
表示一個數組。 標識符本身不是指針,它是一個數組; 然而,它會衰減到一個指針 ,或者如果你願意,就像一個指針一樣。 這就是為什么你可以將它作為一個傳遞出來的原因,如果你想要的話,就像你把它傳遞給foo()
。 現在,如果你引用array
的地址 ,比如&array
, (char*)array
, &array
, &array[0]
都是一樣的 - 指向array
開頭的指針。 在這種情況下,你的foo()
實際上是將一個內存地址寫入array
的內存中。
這是做什么的? 那么,技術答案是未定義的行為。 但我猜它正在寫一個32位整數(一個內存地址)到一塊內存,用來表示一個字符串中的4個8位字符。 所以現在你已經損壞了四個字符。 並且,如果foo()
正在使用malloc()
,則還會引入內存泄漏。
這個很好的部分是你的字符串正好是四個字符,所以這不應該破壞字符串末尾的空終結符'\\0'
。 讓我猜一下,你看到的確是四個垃圾角色?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.