[英]I don't understand pointers, addresses and scopes
以下是我編寫的代碼段,目前正在打印中掙扎。
在我的主要方法中,我使用有效輸入兩次調用函數insertPoint
,例如: insertPoint(42); insertPoint(56);
insertPoint(42); insertPoint(56);
並獲得以下輸出:
A.1 42
B.3 2686700
但是在B.3,我希望它也返回值42,但不會。 我假設2686700指向內存中的某個地址。
#include <stdio.h>
#include <stdlib.h>
struct point {
int value;
struct point* next;
};
struct point *root;
int insertPoint(int value) {
// Graph is empty, set new root
if(root == 0){
struct point newRoot;
newRoot.value = value;
root = &newRoot;
(*root).value = value;
printf("A.1 %d \n", (*root).value); // "A.1 42"
return value;
}
printf("B.3 %d \n", (*root).value); // "B.3 2686700"
/* rest of code here; irrelevant since related variables are not changed */
}
有人知道為什么會這樣嗎? 任何建設性的評論/答案表示贊賞。
如果下降者會向我提供反饋,我也將不勝感激,為什么他們認為我的問題不合適。
如果采用if (root == 0)
分支,則root
將指向struct point newRoot;
這是在if
分支主體內部的堆棧上分配的。 newRoot
結構在離開分支的主體和函數的主體之后(在您的情況下,在return value;
之后)超出范圍return value;
聲明。 但是,全局指針變量root
將繼續指向內存中的該位置(堆棧上)。 該位置上的堆棧存儲器的內容很可能會被其他一些代碼覆蓋,因此從該位置讀取point
(成員)值(例如,通過root
指針)將導致不確定的行為,這就是為什么要得到這種結果的原因。
您可能打算動態分配新的根,例如:
if(root == 0) {
root = (point *) malloc(sizeof(point));
root->value = value;
root->next = NULL;
printf("A.1 %d \n", root->value); // "A.1 42"
return value;
}
別忘了設置next
指針,因為默認情況下它不會為NULL
(除非也許不是malloc
而是使用calloc
來對返回的內存進行零初始化,從而在大多數平台上有效地使next
的值等於NULL
)。 另外,不要忘記釋放動態分配的任何內存:使用malloc
, calloc
或realloc
分配的任何內存都必須稍后使用free
。
您的代碼具有未定義的行為,因為它允許在范圍之外使用指向局部變量的指針。
它發生在這里:
struct point newRoot;
...
root = &newRoot;
問題在於,一旦函數到達}
關閉if
語句, root
就會失效。 對其的任何取消引用都是未定義的行為。 因此,當您這樣做時
printf("B.3 %d \n", (*root).value);
您訪問無效指針指向的內存。
幸運的是,解決此問題的方法很簡單:使用malloc
而不是newRoot
為鏈表元素分配內存:
if(root == 0){
root = malloc(sizeof(struct point));
root->value = value;
printf("A.1 %d \n", (*root).value); // "A.1 42"
return value;
}
當然,在退出程序之前,您需要使用malloc
free
分配的malloc
,以避免內存泄漏。
您創建struct point newRoot;
在函數內部的堆棧上。 由於它在堆棧上,因此在退出此函數時將其銷毀。 此后,任何使用其指針( *root
)的操作都應給出未定義的結果。
您必須了解,堆棧超出范圍時,堆棧中的內容會消失
所以
root = &newRoot;
這里newRoot
在堆棧中。 函數結束newRoot
結束-指針無效
使用malloc
創建newRoot
對象,這樣我可以使函數調用的壽命更長
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.