![](/img/trans.png)
[英]Passing pointer of pointers to function, returning both an int and an address (by parameter)
[英]Initializing local pointers by passing the address of a pointer
我在代碼的幾乎每個部分都看到了以下初始化本地指針的方法。 想要了解這樣做的原因和復雜性。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void initialize_p(char **p)
{
char *p_local = NULL;
p_local=malloc(6);
strcpy(p_local,"sandy");
*p = p_local;
}
int main(void)
{
char *p = NULL;
initialize_p(&p);
printf("Name : %s\n",p);
return 0;
}
就是這樣,我在這里用簡單的字符串顯示。 在我的實際代碼中,它是使用結構完成的。
我有點理解上面的邏輯而且我也沒有。 請明確上述實施方式所涉及的概念。 另外,如果還有其他更好的方法可以讓我知道。
請啟發.. :)
我可能會返回新分配的字符串,而不是將指針作為參數傳遞給指針:
char *initialize(void) {
char *init = "sandy";
char *ret = malloc(sizeof(init)+1);
if (ret != NULL)
strcpy(ret, init);
return ret;
}
int main() {
char *p = initialize();
printf("Name: %s\n", p);
free(p);
return 0;
}
這是一個超出參數。 該函數為您生成結果,並將其保存到您傳遞的參數中。 當結果的大小可能變化,或者參數的類型是不透明時,通常會使用此方法。
就個人而言,我認為返回結果更清晰,並且在需要動態分配時更不容易出錯(如JerryCoffin的答案+1中所示)。
當不需要動態分配時,如果它不是很小的話,則通過引用傳遞它(作為非const參數):
struct t_struct { int a[100]; };
void InitStruct(struct t_struct* pStruct) {
pStruct->a[0] = 11;
...
}
struct t_struct s;
void InitStruct(&s);
如果它很小,你可以考慮按價值返回。
在initialize_p中,分配了一塊內存,並將一些字符串復制到內存中。 為了讓初始化器的調用者獲得這個新的內存塊的地址,指針p的地址被傳遞給initialize_p:
char **p
+---+---+---+---+---+----+
*p -> | s | a | n | d | y | \0 |
+---+---+---+---+---+----+
如果只傳遞* p,那么在函數內設置指針將相當於:
void foo(int a)
{
a=3;
...
}
更好的方法是使用strdup,它與你在函數中做同樣的事情
char* initialize_p()
{
return strdup("sandy");
}
還要確保釋放返回的字符串以避免內存泄漏。
我建議你創建分配和釋放功能對
char *createP()
{
char *p = NULL;
p=malloc(6);
strcpy(p,"sandy");
return p;
}
void freeP(char *p)
{
if (p) free(p);
}
int main(void)
{
char *p = createP();
printf("Name : %s\n",p);
freeP(p);
return 0;
}
清除這個概念? 好吧,在這么簡單的情況下,我沒有看到使用byref輸出參數操作的重點 - 對我來說,面向對象的結構構造函數如果它們像這樣工作則更容易理解:
struct foo *bar = myobj_new(); // uses malloc and returns a pointer
// do something with bar
myobj_destroy(bar); // uses free
有些人認為這個設計很好,因為這個函數的返回值可以用作錯誤/成功代碼(你看過SQLite3嗎?),但我不同意。 我認為函數的主要,最重要的結果應該是返回值,而不是一些輔助內容。 (我傾向於編寫庫,其中通過返回NULL並設置byref傳遞的錯誤代碼來指示失敗)。
我能想到的唯一有效的場景是,傳遞這樣的參數更合乎邏輯或更對稱。 例如,想象一個非常奇怪的排序函數,類似於C stdlib函數qsort()
,但需要它的比較函數本身在需要時交換兩個元素。 比較函數顯然需要通過參數訪問它的兩個參數來交換它們,但是為了優化算法,將原始遇到的順序返回給調用者排序函數也是有用的。 所以這個比較函數可能是這樣的:
int compare(void *a, void *b)
{
int x = *(int *)a;
int y = *(int *)b;
if (x > y)
{
*(int *)a = y;
*(int *)b = x;
return +1;
} else if (x < x) {
return -1;
}
return 0;
}
嗯,差不多就是我的意見......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.