簡體   English   中英

創建數組“正常”和malloc之間的區別

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM