繁体   English   中英

没有C的数组和动态列表的指针和算术的指针

[英]pointer to pointer & Arithmetic without array & dynamic list of list in C

(更新)

我们可以在不引用数组的情况下使用指向“指向指针的指针”的指针算法吗?

例:

int val = 10;
int *b = &val; // UPDATE here:I create a pointer b now
int **a = &b;
**a = 12; //change val's value through a
int *c = (int *)malloc(sizeof(int)); // UPDATE here
*(a+1) = c // Is this OK?

我已经在CLion中进行了尝试,它可以编译并且似乎正常工作。 但是我不确定内存泄漏或覆盖等问题。但是,如果我们可以做到这一点,那么,如果我们想实现一个链表,是否可以定义一个指向Node的指针?

struct Node{
  int val;
  Node *next;
}

然后,如果定义Node ** pathList,则可以使用指针算法获取路径列表,每个路径都包含一个Node?列表。

Node **pathList;
Node *firstPath = (Node *)malloc(sizeof(Node));
pathList = &firstPath;
...//add new Node to firstPath..
Node *secondPath = (Node *)malloc(sizeof(Node));
*(pathList+1) = secondPath;// IS THIS LEAGLE?
*(pathList+1) = secondPath;// IS THIS LEAGLE?

是的,这会在您的代码中引起问题。 因为pathList+1将超过您分配的存储块。 并且您取消引用此表达式,将导致未定义的行为。

另外关于您的示例-

int **a;
*a = &val; // a now points to a pointer to val

这也是不正确的 ,因为a 未初始化 ,将其取消引用将再次导致UB。

在这两种情况下,您都需要先为指针分配内存,然后再执行操作。

就上述arneyCU的答案而言,您毫无疑问根本不希望** “指向指针的指针”语义。 相反,您可能想要这样:

int *a;
a = &val;

内容如下:

  • a是“指向整数的指针”。
  • 分配给a变量的地址, val

这个语法:

*a = &val;

将被读取为:

  • 变量val的地址“分配给* a指向的int ”。

...并且C会抱怨您正在为一个整数分配地址值,而没有使用类型转换来表示您知道自己在做什么。

是的,C语言确实允许您将任何指针视为数组,例如a[3] ,该数组计算“第三个元素,从零开始计数”的地址。 实际的内存偏移量将是3 * sizeof(*a) 应该强调的是,C语言假定您知道自己在做什么!

我对C内存分配问题进行了一些研究,并为我对指针和数组的困惑找到了一些详细的解释。

  1. 当我们执行指针算术时,编译器真正要做的是将其存储的地址增加sizeof(type)的数量。 当我们两次调用malloc时,下一个malloc分配的内存块不一定紧挨着最后一个。 所以这样做

    Node *secondPath = (Node *)malloc(sizeof(Node)); *(pathList+1) = secondPath;

我们很危险地覆盖存储在地址*(pathList + 1)中的值;

  1. 根据定义,由于连续位于内存中的一个type块是一个type数组,因此在数组和指针之间产生了一种有趣的关系。

  2. 我们可以执行以下操作:

然后:

int *ptr;    
ptr = (*int) malloc(sizeof(int)*N)

其中N是您需要的元素数。 在此定义之后,您可以像使用常规数组一样使用ptr。 例如:

ptr [i]

我了解到,为了正确使用指针算法,我们需要首先分配内存。

:-)

一些不错的参考: Malloc 指针和数组

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM