[英]How do I change a pointers value in a function in C
代碼是:
int main(int argc, const char* argv[] )
{
struct node * initialpointer=NULL;
insert("asd", initialpointer, 1);
if(initialpointer!=NULL)
printf("isnotnull");
if (initialpointer==NULL)
printf("isnull");
}
insert(char* x,struct node * initialpointer, int numberofelements){
struct node B;
B.word = x;
B.parent = NULL;
B.leftchild = NULL;
B.rightchild = NULL;
printf("%d", 12);
if ( initialpointer == NULL){
initialpointer = &B;
B.parent = NULL;
}
}
所以最后,我希望initialpointer
指向nde B所在的位置,但是在main方法中,它打印的結果為null。 那么,如何永久更改函數插入中的initialpointer
?
不要返回指向局部變量的指針,這將導致指針懸空:
struct node B;
...
initialpointer = &B;
您需要將指針傳遞給一個指向struct node
,以insert()
和malloc()
一個新的struct node
內insert()
insert(char* x,struct node ** initialpointer, int numberofelements)
{
if (NULL == *initialpointer)
{
*initialpointer = malloc(sizeof(struct node));
if (*initialpointer)
{
/* Note: you should probably make a copy of 'x',
using 'strdup()' or similar, otherwise there
is requiremenet that 'x' exist for the lifetime
of '*initialpointer': which would be error prone. */
(*initialpointer)->word = x;
(*initialpointer)->parent = NULL;
(*initialpointer)->leftchild = NULL;
(*initialpointer)->rightchild = NULL;
}
}
}
這保留了原始insert()
的邏輯,因為只有當initialpointer
為NULL
才應創建一個node
並將其分配給initialpointer
。
並調用它:
struct node * initialpointer=NULL;
insert("asd", &initialpointer, 1);
記住在不再需要時free()
它:
free(initialpointer);
struct node * initialpointer=NULL;
insert("asd", &initialpointer, 1);
...
void insert(char* x,struct node ** initialpointer, int numberofelements){
...
if ( *initialpointer == NULL){
*initialpointer = &B;
但是請記住,這也不適用於當前的B
作為auto(局部)變量。
您必須malloc()
B
。
而且您在if
語句中缺少else
分支。
根據@Paul Mitchell的評論進行編輯。
int main(int argc, const char* argv[] )
{
struct node* initialpointer = insert("asd");
if ( initialpointer == NULL )
/* handle the error */
/* remember to free() all the allocated nodes */
}
struct node* insert(char* x)
{
struct node* initialpointer = (struct node*)malloc(sizeof(struct node));
if ( initialpointer == NULL)
return NULL;
initialpointer.word = x;
initialpointer.parent = NULL;
initialpointer.leftchild = NULL;
initialpointer.rightchild = NULL;
return initialpointer;
}
這將分配一個節點(我已經刪除了numberofelements
參數)。
要為一個以上的節點分配空間,您必須將指針傳遞給指針。 但是,如果我理解您的意圖,那么您希望節點成為鏈接結構(可能是樹)的一部分,因此您無需為節點創建容器,因為您可以遍歷結構來訪問節點。
您的代碼有幾個問題。
首先是您遇到的問題。 您傳遞給insert
的指針是通過副本傳遞的; 該函數將獲得一份副本,而main
看不到您所做的更改。 解決方案是將指針傳遞給該指針。 有關其外觀的標准庫示例,請參見POSIX函數strtol
。
第二個問題是您要返回指向本地自動(即堆棧分配)變量的指針。 由於堆棧是在函數退出時釋放的,因此當指針返回main
時,該指針將指向無效內存。 因此,您需要從堆中分配B
因此,修復問題:
int main(int argc, const char* argv[] )
{
struct node * initialpointer=NULL;
insert("asd", &initialpointer, 1);
if(initialpointer!=NULL)
printf("isnotnull");
if (initialpointer==NULL)
printf("isnull");
}
insert(char* x,struct node ** initialpointer, int numberofelements){
struct node *B;
B = (struct node*)malloc(sizeof(struct node));
B->word = x;
B->parent = NULL;
B->leftchild = NULL;
B->rightchild = NULL;
printf("%d", 12);
if ( *initialpointer == NULL){
*initialpointer = B;
B->parent = NULL;
}
}
由於兩個原因,這是有問題的。
首先,您要更改局部作用域變量,因為initialpointer
是函數的參數。 這意味着,不管其類型如何,僅在您的insert
函數內部才可以看到對變量本身的寫操作。 如果您正在寫*initialpointer
,那將是完全不同的故事。
現在,更成問題的是B
是一個位於函數內部堆棧上的局部變量。 保留該功能后, B
的存儲位置將無效。 因此,如果將指針返回到B
,則在insert
之外訪問該對象將調用未定義的行為,並且很可能行不通(您極有可能未更改該特定位置,但這很幸運)。
您可能想要而不是
initialpointer = &B;
這是:
*initialpointer = B;
這會將B
對象復制到指針變量引用的存儲位置。 現在B
可以超出范圍了,因為您initialpointer
所有內容復制到了位於main內的initialpointer
變量中。
需要注意的是initialpointer
內部變量main
是一個比一個完全不同的東西insert
!
最后一件事,給變量名稱以大寫字母開頭的名稱在我到目前為止遇到的任何命名方案中都是無效的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.