简体   繁体   English

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

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

(UPDATE) (更新)

Could we use pointer arithmetic to a "pointer to pointer" without reference to an array? 我们可以在不引用数组的情况下使用指向“指向指针的指针”的指针算法吗?

Example: 例:

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?

I have tried this in CLion, it compiles and seem working normally. 我已经在CLion中进行了尝试,它可以编译并且似乎正常工作。 But I kind of feel unsure about the memory leak or overwrite, etc. But if we could do this, then, if we'd like to implement a linked list, could we just define a pointer to a pointer to the Node ? 但是我不确定内存泄漏或覆盖等问题。但是,如果我们可以做到这一点,那么,如果我们想实现一个链表,是否可以定义一个指向Node的指针?

struct Node{
  int val;
  Node *next;
}

Then, if we define Node ** pathList, we could use the pointer arithmetic to get a list of path, each of which contains a list of Node? 然后,如果定义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?

Yes, this would cause problem in your code . 是的,这会在您的代码中引起问题。 As pathList+1 would go past the memory block you allocated. 因为pathList+1将超过您分配的存储块。 And you dereference this expression, would result in undefined behaviour. 并且您取消引用此表达式,将导致未定义的行为。

Also regarding your example - 另外关于您的示例-

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

This is also not correct , as a is uninitialized and dereferencing it would result into again UB. 这也是不正确的 ,因为a 未初始化 ,将其取消引用将再次导致UB。

In both the cases you need first allocate memory to the pointers and then perform your operations. 在这两种情况下,您都需要先为指针分配内存,然后再执行操作。

In the case of arneyCU's answer above, you undoubtedly do not want the ** "a pointer to a pointer to" semantics at all. 就上述arneyCU的答案而言,您毫无疑问根本不希望** “指向指针的指针”语义。 Instead, you probably want this: 相反,您可能想要这样:

int *a;
a = &val;

Which is read as follows: 内容如下:

  • a is "a pointer to an integer." a是“指向整数的指针”。
  • Assign to a the address of the variable, val . 分配给a变量的地址, val

This syntax: 这个语法:

*a = &val;

would be read as: 将被读取为:

  • "Assign to *the int that a points to," the address of the variable, val . 变量val的地址“分配给* a指向的int ”。

... and C would complain that you are assigning an address value to an integer without using a typecast to say that you know what you are doing. ...并且C会抱怨您正在为一个整数分配地址值,而没有使用类型转换来表示您知道自己在做什么。

Yes, the C language does allow you to treat any pointer as an array, eg a[3] , which computes the address of "the third element, counting from zero." 是的,C语言确实允许您将任何指针视为数组,例如a[3] ,该数组计算“第三个元素,从零开始计数”的地址。 The actual memory offset would be 3 * sizeof(*a) . 实际的内存偏移量将是3 * sizeof(*a) It should be emphasized that the C language assumes that you know what you are doing! 应该强调的是,C语言假定您知道自己在做什么!

I have did some research about the C memory allocation problem and found some detailed explanations for my confusions about pointers and arrays. 我对C内存分配问题进行了一些研究,并为我对指针和数组的困惑找到了一些详细的解释。

  1. When we do pointer arithmetic, what the complier really does is to increments the address it stores by the amount sizeof(type). 当我们执行指针算术时,编译器真正要做的是将其存储的地址增加sizeof(type)的数量。 When we call malloc twice, the block of memory that the next malloc allocates isn't necessarily next to the last lot. 当我们两次调用malloc时,下一个malloc分配的内存块不一定紧挨着最后一个。 So by doing 所以这样做

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

We dangerously overwrite the value stored in the address *(pathList+1); 我们很危险地覆盖存储在地址*(pathList + 1)中的值;

  1. Since a block of type located contiguously in memory is, by definition, an array of type , this brings up an interesting relationship between arrays and pointers. 根据定义,由于连续位于内存中的一个type块是一个type数组,因此在数组和指针之间产生了一种有趣的关系。

  2. We can do the following: 我们可以执行以下操作:

and then later on: 然后:

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

where N is the number of elements that you need. 其中N是您需要的元素数。 After this definition you can use ptr as if it was a conventional array. 在此定义之后,您可以像使用常规数组一样使用ptr。 For example: 例如:

ptr[i] ptr [i]

I learnt that, in order to use pointer arithmetic properly, we need to first allocate memories first. 我了解到,为了正确使用指针算法,我们需要首先分配内存。

:-) :-)

Some nice references: Malloc Pointers and Arrays 一些不错的参考: Malloc 指针和数组

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

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