簡體   English   中英

我是否需要為指針分配空間以及為內存區域分配空間,其地址將保存在指向指針和重新分配的指針中的指針中

[英]do I need to allocate space for pointer as well as space for memory area whose address will be kept in pointer in pointer to pointer and realloc

我有這個代碼

int main(int argc, char *argv[])
{

    int i=1;
    char **m=malloc(sizeof(char *)*i);
    printf("%zu\n",sizeof *m);
    m[0]=malloc(strlen("hello")+1);
    strcpy(m[0],"hello");
    printf("%s\n", m[0]);
    i=2;
    m=(char **)realloc(m,sizeof (char *)*i);
    m[1]=malloc(strlen("hi")+1);
    strcpy(m[1],"hi");
    printf("%s %s \n",m[0],m[1] );
    // TODO: write proper cleanup code just for good habits.
    return 0;
}

這就是我分配指針char **m 8 字節單字符指針的方式

    int i=1;
    char **m=malloc(sizeof(char *)*i);

這就是我分配地址將保留在 m[0] 中的空間區域的方式

m[0]=malloc(strlen("hello")+1);
strcpy(m[0],"hello");
printf("%s\n", m[0]);

我想知道這通常是如何完成的。 我的意思是為指針分配空間,然后在指針將持有的內存中分配空間。

m[0]=malloc(strlen("hello")+1); 與此相同*(m+0)=malloc(strlen("hello")+1); 並且這樣做m[1]=malloc(strlen("hi")+1); 這個*(m+1)=malloc(strlen("hi")+1);

我在分配m=(char **)realloc(m,sizeof (char *)*i); 之前m[1]=malloc(strlen("hi")+1);

上面的代碼有什么問題嗎。 我在這個動態內存/重新分配字符串數組上看到了類似的代碼

誰能用這個語句解釋一下char **m=malloc(sizeof(char *)*i); 我正在分配 char 類型的 8 字節單指針,但使用此語句m=(char **)realloc(m,sizeof (char *)*i); 為什么我沒有收到堆棧 smaching 檢測到的錯誤。 realloc 究竟是如何工作的。 誰能給我 realloc 函數的鏈接或對此做一些解釋

你的代碼對我來說很好。 是的,如果您要存儲一個字符串數組,並且您事先不知道該數組中有多少個字符串,那么使用malloc為指針數組分配空間是完全沒問題的。 您還需要以某種方式為字符串本身獲取內存,並且使用自己的malloc調用分配每個字符串是完全沒問題的。

您寫的使用realloc的行很好; 它擴展了您為指針分配的內存區域,以便它現在可以容納 2 個指針,而不僅僅是 1 個。當realloc函數執行此操作時,它可能需要將內存分配移動到不同的地址,以便這就是為什么你必須像你一樣覆蓋m 這里沒有堆棧粉碎。 另外,請注意,並非每個平台上的指針都是 8 個字節; 這就是為什么寫sizeof(char *)而不是8是明智的。

要查找有關realloc更多文檔,您可以查看 C++ 標准或 POSIX 標准,但也許最適合解決此問題的地方是C 標准,它在第 314 頁上記錄了realloc

我想知道這通常是如何完成的。 我的意思是為指針分配空間,然后在指針將持有的內存中分配空間。

這取決於您要實現的目標。 如果您希望分配具有單獨長度的未指定數量的字符串,那么您的代碼幾乎是正確的方法。

如果你希望有固定數量的不同長度的字符串,你可以只做char* arr [n]; 然后只 malloc 每個arr[i]

或者,如果您希望擁有固定最大長度的固定數量的字符串,您可以使用二維字符數組char arr [x][y]; ,並且根本沒有 malloc。

m[0]=malloc(strlen("hello")+1); 與此相同*(m+0)=malloc(strlen("hello")+1);

是的, m[0] 100% 等價於*((m)+(0)) 請參閱指針是否支持“數組樣式索引”?

上面的代碼有什么問題嗎

不是真的,除了風格和性能問題。 它可以選擇重寫如下:

char** m = malloc(sizeof(*m) * i); // subjective style change
m[0]=malloc(sizeof("hello"));      // compile-time calculation, better performance

為什么我沒有收到堆棧 smaching 檢測到的錯誤

你為什么要得到那個? 此處存儲在堆棧中的唯一內容是char**本身。 其余的存儲在堆上。

realloc 究竟是如何工作的。 誰能給我 realloc 函數的鏈接或對此做一些解釋

它的工作原理與您使用的差不多,盡管迂腐地您不應該將結果存儲在與傳遞的指針相同的指針中,以防 realloc 失敗並且您希望繼續使用舊數據。 不過,這是一個非常小的評論,因為萬一 realloc 失敗,這要么意味着您對內存提出了不切實際的請求,要么您系統上的 RAM 已過時,無論如何您都不太可能繼續執行。

realloc的規范文檔是 C 標准 C17 7.22.3.5:

 #include <stdlib.h> void *realloc(void *ptr, size_t size);

realloc函數釋放ptr指向的舊對象,並返回一個指向大小由 size 指定的新對象的指針。 新對象的內容應與釋放前的舊對象的內容相同,直到新舊大小中較小的一個。 新對象中超出舊對象大小的任何字節都具有不確定的值。

如果ptr是空指針,則realloc函數的行為類似於指定大小的malloc函數。 否則,如果ptr與之前由內存管理函數返回的指針不匹配,或者如果空間已通過調用 free 或realloc函數釋放,則行為未定義。 如果不能為新對象分配內存,則舊對象不會被釋放並且其值不變。

退貨
realloc函數返回一個指向新對象的指針(它可能與指向舊對象的指針具有相同的值),如果無法分配新對象,則返回空指針。

值得注意的是,不能保證返回的指針始終與舊指針具有相同的值,因此正確使用將是:

char* tmp = realloc(arr, size);
if(tmp == NULL)
{
  /* error handling */
}
arr = tmp;

(其中tmparr具有相同的類型。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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