简体   繁体   中英

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. 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 ?

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 *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. 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.

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. Instead, you probably want this:

int *a;
a = &val;

Which is read as follows:

  • a is "a pointer to an integer."
  • Assign to a the address of the variable, val .

This syntax:

*a = &val;

would be read as:

  • "Assign to *the int that a points to," the address of the variable, val .

... 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.

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." The actual memory offset would be 3 * sizeof(*a) . It should be emphasized that the C language assumes that you know what you are doing!

I have did some research about the C memory allocation problem and found some detailed explanations for my confusions about pointers and arrays.

  1. When we do pointer arithmetic, what the complier really does is to increments the address it stores by the amount sizeof(type). When we call malloc twice, the block of memory that the next malloc allocates isn't necessarily next to the last lot. So by doing

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

We dangerously overwrite the value stored in the address *(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.

  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. After this definition you can use ptr as if it was a conventional array. For example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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