我试图了解这段代码的作用(以及是否允许):
int * A;
int * B;
A = (int *)malloc( size_t somenumber );
B = A;
// bunch of stuff using B, B++, etc.
我读过的所有内容总是显示使用引用运算符 ( &
) 或取消引用运算符 ( ) 将事物等同于指针*
。
这种对等有什么作用?
而且,当我最终free(A)
会发生什么B
?
这不等于两个指针,它是一个指针赋值。一次
B = A;
执行时,两个指针都指向同一个内存区域:访问*B
变得与访问完全相同*A
,B[i]
变得等价于A[i]
,依此类推。
请注意,释放A
使B
dangling,反之亦然。换句话说,在调用之后
free(A);
访问*B
成为未定义的行为。
当涉及到指针混淆时,图片总是很好的:
int * A; // create a pointer to an int named "A"
int * B; // create a pointer to an int named "B"
A = (int *)malloc( size_t somenumber ); // Allocate A some memory, now B is an
// uninitialized pointer; A is initialized,
// but just to uninitialized memory
从概念上讲:
B = A; // Assign B to the value of A (The uninitialized memory)
free(A);
所以毕竟我认为你可以看到正在发生的事情。B 被分配了 A 的值,这是已分配和未初始化的内存块。所以现在你只有两个指向同一个区域的指针。
至于free()
问题,正如您在调用时所看到的那样free(A);
,A 和 B 都指向同一个区域,那里不再为您的程序分配任何内容。这就是为什么在调用free()
时最好将指针设置为NULL
.
现在回到你最初的问题。如果您想检查两个指针==
:
int * A; // create a pointer to an int named "A"
int * B; // create a pointer to an int named "B"
A = (int *)malloc( size_t somenumber ); // Allocate A some memory, now B is an
// uninitialized pointer; A is initialized,
// but just to uninitialized memory
if(B == A){
// The pointers are pointing to the same thing!
}
if(*B == *A){
// The values these pointers are pointing to is the same!
}
更新
因此,要回答您更新的问题,我们需要更改B
.
int *A; // A is a pointer to an int
int **B; // B is a pointer to a pointer to an int
B = &A; // B is now pointing to A
为了说明这一点:
对于B=*A
:
int *A;
int B;
A = malloc(sizeof(int));
*A = 5;
B = *A;
这是对 的尊重A
。因此,您只需将 A 指向的任何内容分配给B
,在本例中为 5
这不是“等同”,无论这意味着什么,这只是分配。指针A
的值(您刚刚分配的内存块的地址)被复制到指针B
中。
当你free(A)
,B
成为所谓的“悬空指针”,即不再有效使用的指针。
您只是将一个指针分配给另一个。现在B
将指向任何A
指向的东西。如果您免费A
,它也将免费B
(不知道如何表达这一点,因为只会发生一种free
情况)。至于&
你可能的意思是:
int *A;
int B;
A = &B;
这意味着使指针A
指向整数B
,或将B
地址存储在A
.
这只是将两个指针设置为指向相同的内存地址。
如果稍后将其中一个更改为指向另一个地址,这不会影响另一个——尽管取消引用和更改指向的值当然也可以从另一个指针中看到。
如果其中一个指针被释放,则另一个副本将立即非法取消引用(假设它在分配后保持相同的值)。
编写此类代码的一个实际原因可能是A
在分配的内存开始时应该保持“固定”,而B
在程序执行期间将在分配的范围内漫游。您需要A
释放内存(也许作为基线),但出于某种原因使用另一个“临时”指针进入该内存会更方便。
在上述情况下,当你 时free(A)
,指针 A 指向的内存块(指针 B 也指向同一个块)将被释放并将资源返回给系统。存储在 A 或 B 中的地址仍然存在(我们称之为悬空指针 - 指向某个内存块的先前位置的指针)。通常,我们在调用后将其设置为 NULL free()
,至少对于现代操作系统而言,当我们稍后尝试错误地引用指针时,会导致系统发出 SIGSEGV 和核心转储信号。否则,当指针指向的相同地址以某种方式再次分配给您时,程序可能会显示奇怪的行为(有时会崩溃,有时会继续,有错误的输出)。