【问题标题】:Can we assign address to a pointer by another variable containing address of some other variable we want Pointer to point to?我们可以通过另一个包含我们希望指针指向的其他变量的地址的变量将地址分配给指针吗?
【发布时间】:2019-08-22 20:11:02
【问题描述】:

我试图通过另一个变量手动提供地址,而不是使用&

#include <stdio.h>

int main()
{
    int ab = 99;
    int *p;
    int f = &ab;
    p = f;
    printf("%d\n%d\n%d\n%d\n", &ab, p, f, p); // prints same address
    printf("%d\n", *p); // By adding this line, gives SEGFAULT
}

./a.out 给:

284008584
284008584
284008584
284008584
Segmentation fault (core dumped)

【问题讨论】:

  • 您的编译器有义务发出有关此错误代码的诊断消息。

标签: c pointers memory-address


【解决方案1】:

您正在尝试将指针值分配给 int。如果指针大于系统上的int(这很可能是在 64 位操作系统上运行),那么您最终会在转换中丢失数据。然后当你转换回来时,你会得到一个无效的指针,并且试图取消引用这个指针会导致崩溃。

您还通过使用错误的格式说明符来打印指针来调用未定义的行为。您应该使用%p,并且应该将指针转换为void *(需要转换为void * 的少数情况之一)。如果您这样做,转换中的数据丢失将变得很明显。

【讨论】:

  • @ShreyashChauhan 实际上使用的正确类型是uintptr_t。这保证足够大以保存转换后的指针值。您还可以使用%tu 进行打印。
  • 我认为%p 会更好。 ptrdiff_t 不保证是指针的大小。
【解决方案2】:
  1. 请将编译器的警告级别提高到最大,对于 GCC,它的 -Wall -Wextra,如果你也喜欢 -pedantic。因为:
  2. 您的int f = &amp;ab; 行有错误。 RHS 上的表达式是int 的地址,而LHS 上的变量是int

在您的系统上,整数和指针的大小可能不同,这就是为什么要取消引用从整数段错误设置的指针。

【讨论】:

  • 老兄,这只是将您的错误隐藏在相同大小的后面。但这仍然是一个错误。正确的做法是将f改成指向int的指针。
  • 我知道正确的方法,我只是在玩数字和地址
  • 好吧,如果你写了这个来节省我们思考这个问题的时间,那就太好了。请下次这样做。 ;-) 顺便说一句,打印地址的正确方法是“%p”。
  • 是的,我应该这样做,下次我会处理的。 %d 比 %p 更具可读性,无论如何谢谢 :)
【解决方案3】:

除了上述关于指针和整数不同大小的所有正确答案之外,
如果您修改打印地址的行以使用正确的格式修饰符,您将看到输出地址不同,这是由于从指向 int 的指针转换期间的丢失:

printf("%p\n%x\n%p\n",&ab,p,f); // prints same address

例子:

0x7ffc8b716ea8
8b716ea8
0x8b716ea8

【讨论】:

    【解决方案4】:

    检查int的大小和int *的大小是否相同,以便整数变量可以保存地址而不会丢失任何数据。用下面的代码检查一下:

    printf("%lu, %lu \n", sizeof(int*), sizeof(int));
    

    如果两者不相同,则可能会面临错误。

    我建议采用变量类型uintptr_t,它可以容纳指针的地址。

    【讨论】:

    • long long 几乎肯定不是正确的类型。 long 通常是,但这仍然不是最好的答案。
    猜你喜欢
    • 2021-01-18
    • 2020-12-30
    • 2011-08-23
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多