在C中,如果将双指针分配给值,为什么指针变量为0?

时间:2019-01-05 15:26:47

标签: c

class test {
    constructor() {
        println("test constructor")
    }

    companion object {
        operator fun invoke() = println("test companion invocation")
    }

    operator fun invoke() = println("test invocation overload")
}

fun main(args: Array<String>) {
    val test = test() // class wins with companion. Also local variable shadows outer scope.

    val test1 = test() // calls invoke function of local variable
}

上面的代码打印:0和10

为什么ptr 0?

如果ptr为0,代码如何显示** ptr = 10?

我尝试打印* ptr。

这导致了分割错误(因为ptr为0)。

那么,为什么不在** ptr处抛出分段错误呢?

这与编译器有关吗?

PS:我正在使用https://www.onlinegdb.com/online_c_compiler运行此代码。

2 个答案:

答案 0 :(得分:4)

指针ptr未初始化。您的代码调用了未定义的行为,因为您要取消引用未初始化的指针。

答案 1 :(得分:3)

您将指针分配给指针本身,而不是所引用的对象。

int v = 10;

int *ptr = &v;
int **ptrptr = &ptr;

printf("%d\n", **ptrptr);
  

那么,为什么不在** ptr处抛出分段错误呢?

根据事件。这是UB,您的指针具有随机值。该值指向具有随机值的另一个位置。然后您取消引用第二个。因此,如果这些随机值指向分配给程序的内存中的位置,则不会进行段错误。如果没有,它将出现段错误。

为什么要打印010?因为在这种情况下,编译器优化了所有指针操作,并假定未初始化的指针为NULL,所以只需打印常量值即可:

main:
        push    {r4, lr}
        mov     r1, #0
        ldr     r0, .L3
        bl      printf
        mov     r1, #10
        ldr     r0, .L3+4
        bl      printf
        mov     r0, #0
        pop     {r4, pc}
.L3:
        .word   .LC0
        .word   .LC1
.LC0:
        .ascii  "%x\012\000"
.LC1:
        .ascii  "%d\012\000"