having a bit of problem to understand pointer

Thread Starter

skyr6546

Joined Mar 22, 2019
73
I'm having a bit of a problem to understand pointer with one of my program
Code:
#include<stdio.h>
#include<stdlib.h>
 
struct s{
    int *p;    // member structure type int
    struct s *ps; // member structure type struct
};
 
int  main (){
  struct s *psv = malloc(sizeof (struct s)); //structure variable type struct
 
  if (psv == NULL) {
    printf ("Malloc failed\n");
  }
  printf ("Malloc Allocated \n");
 
  psv->p;
  psv->ps;
 
  free (psv);
 
  return 0;
}
Pointer variable hold memory location, int *p; it means it hold the only integer

I'm having a bit of a problem to understand following lines
Code:
  psv->p;
  psv->ps;
There are three pointer one integer pointer and two pointer to structure.

Is psv point content of p that is memory location of variable ? but it can be only int type
Is psv point content of ps that is memory location of variable but it can be any type int, char, flot
 

Papabravo

Joined Feb 24, 2006
21,225
It helps if you read them right to left.

p is a pointer to an integer, contained in the structure of type s, pointed to by psv
ps is a pointer to a structure of type s, contained in the structure of type s, pointed at by psv

That wasn't so bad -- was it?
 

Thread Starter

skyr6546

Joined Mar 22, 2019
73
ps is a pointer to a structure of type s, contained in the structure of type s, pointed at by psv
Is it correct

psv point memory location of variable p and value stored at this address can be only int type

psv point memory location of variable and value stored at this can be any type int, char, flot and long
 

402DF855

Joined Feb 9, 2013
271
psv is a pointer to a struct s.
psv->p is a pointer to an integer.
psv->ps is a pointer to a struct s;

Most likely you would follow the malloc with something like:
C:
psv->p = &some_integer;
// then
psv->ps = malloc(sizeof (struct s));
// or
psv->ps = NULL;
BTW, the following code does NOTHING.
C:
psv->p;
psv->ps;
 

Papabravo

Joined Feb 24, 2006
21,225
Is it correct

psv point memory location of variable p, which is a pointer, and the value stored at this address can be only int type -- yes this is correct

psv point memory location of variable and value stored at this can be any type int, char, float and long -- no this is incorrect.
psv ONLY points to one place. It points to the beginning of a structure of type s. At offset 0 in this structure is a pointer p, that points to a variable of type int. If the length of a pointer is always 4 bytes, then at offset 4 in the structure s is another pointer ps, that points to a structure of type s. Nobody said anything about variables of other types. The total length of a structure of type s is 8 bytes, which is also the length of two pointers.

The machine executing the code doesn't have "types" associated with pointers but the compiler will keep you from making a fool of yourself.
 

WBahn

Joined Mar 31, 2012
30,045
I'm having a bit of a problem to understand pointer with one of my program
Code:
#include<stdio.h>
#include<stdlib.h>

struct s{
    int *p;    // member structure type int
    struct s *ps; // member structure type struct
};

int  main (){
  struct s *psv = malloc(sizeof (struct s)); //structure variable type struct

  if (psv == NULL) {
    printf ("Malloc failed\n");
  }
  printf ("Malloc Allocated \n");

  psv->p;
  psv->ps;

  free (psv);

  return 0;
}
Pointer variable hold memory location, int *p; it means it hold the only integer
p is a variable that points to a value of type int (read it backwards and it flows a bit better).

The value stored in p is a memory address.

The value stored at that memory address is expected to be a value represented as an int.

I'm having a bit of a problem to understand following lines
Code:
  psv->p;
  psv->ps;
That could be because they don't do anything and you are expecting that they should.

Just as

Code:
int n;

n;
would do nothing more than evaluate to the value stored in 'n' but then not use it or change it, psv->p evaluates to the value stored in the variable 'p' within the structure pointed to by the variable psv. The same with psv->ps.

Since these were not initialized, they probably contain random junk. When you allocate memory for a structure, it is good practice to properly initialize all pointer variables (if not ALL variables) contained within it. Either allocate memory for what they point to or set them to NULL so that you can determine that they don't point to anything.

There are three pointer one integer pointer and two pointer to structure.

Is psv point content of p that is memory location of variable ? but it can be only int type
Is psv point content of ps that is memory location of variable but it can be any type int, char, flot
psv is a pointer to a structure of type s.

psv->p is a pointer to a variable of type int.
psv->ps is a pointer to a structure of type s.
 

Thread Starter

skyr6546

Joined Mar 22, 2019
73
I thank all of you. I think it's better then previous

Malloc Allocated
address of psv1 : 00BE13D8
address of psv1->n = 00BE13D8
address of psv1->p = 00BE13DC
address of psv1->ps= 00BE13E0

C:
#include<stdio.h>
#include<stdlib.h>
struct s{
    int n;
    int *p;    // member structure type int
    struct s *ps; // member structure type struct
};
int  main (){ 
  struct s *psv1 = malloc(sizeof (struct s)); //structure variable type struct
  struct s *psv2;

  if (psv1 == NULL) {
    printf ("Malloc failed\n");
  }
  printf ("Malloc Allocated \n");
  printf("address of psv1 : %p \n", (void*)psv1);
  psv1->n = 2;
  psv1->p;
  psv2->ps = psv1;
  printf("address of psv1->n = %p \n", (void*)&psv1->n);
  printf("address of psv1->p = %p \n", (void*)&psv1->p);  
  printf("address of psv1->ps= %p \n", (void*)&psv1->ps);
  free (psv1);
  return 0;
}
 

402DF855

Joined Feb 9, 2013
271
C:
  printf("VALUE of psv1 : %p \n", (void*)psv1);
  printf("ADDRESS of psv1 : %p \n", (void*)&psv1);

  psv1->p; // DOES NOTHING
  psv2->ps = psv1; // Bad Idea! VALUE of psv2 is undefined (uninitialized).
 

WBahn

Joined Mar 31, 2012
30,045
psv ONLY points to one place. It points to the beginning of a structure of type s. At offset 0 in this structure is a pointer p, that points to a variable of type int. If the length of a pointer is always 4 bytes, then at offset 4 in the structure s is another pointer ps, that points to a structure of type s. Nobody said anything about variables of other types. The total length of a structure of type s is 8 bytes, which is also the length of two pointers.

The machine executing the code doesn't have "types" associated with pointers but the compiler will keep you from making a fool of yourself.
The length of a pointer is not always four bytes -- increasingly most compilers in use are targeting 64-bit architectures and most (not all) of those use 8-bit pointers.
 

WBahn

Joined Mar 31, 2012
30,045
I thank all of you. I think it's better then previous

Malloc Allocated
address of psv1 : 00BE13D8
address of psv1->n = 00BE13D8
address of psv1->p = 00BE13DC
address of psv1->ps= 00BE13E0

C:
#include<stdio.h>
#include<stdlib.h>
struct s{
    int n;
    int *p;    // member structure type int
    struct s *ps; // member structure type struct
};
int  main (){
  struct s *psv1 = malloc(sizeof (struct s)); //structure variable type struct
  struct s *psv2;

  if (psv1 == NULL) {
    printf ("Malloc failed\n");
  }
  printf ("Malloc Allocated \n");
  printf("address of psv1 : %p \n", (void*)psv1);
  psv1->n = 2;
  psv1->p;
  psv2->ps = psv1;
  printf("address of psv1->n = %p \n", (void*)&psv1->n);
  printf("address of psv1->p = %p \n", (void*)&psv1->p); 
  printf("address of psv1->ps= %p \n", (void*)&psv1->ps);
  free (psv1);
  return 0;
}
You should NEVER dereference any pointer that has not been properly initialized. Just dereferencing it can cause your program to misbehave or crash or worse.

You did this when you did

psv2->ps = psv1;

You never initialized psv2 and so this variable contains garbage which, when you dereference it by doing psv2->ps you are trying to access a structure at a memory location that is essentially random. What happens is anyone's guess (it's undefined behavior). You then compound this problem by actually writing something to that structure -- if the prior dereference happened to be benign because the random memory location turned out to be someplace that you were allowed to access, you have now overwritten memory at an unpredictable location and that memory was possibly being used for some other purpose already and you've just altered it, again invoking undefined behavior.
 

ApacheKid

Joined Jan 12, 2015
1,609
I'm going to show you a simple technique that will make your C code much more readable, easier to comprehend when debugging etc.

Replace the code in your OP with this:

Code:
#include<stdio.h>
#include<stdlib.h>

// This associates 'Item' and 'Item_ptr' with 'item'
typedef struct item Item, * Item_ptr;

// Defines a type Int_ptr that is a pointer to an int.
typedef  int* Int_ptr;

// This declares the structure of 'item'
// Once this is declared we never use 'item' only 'Item' and 'Item_ptr' types.
typedef struct item
{
    Int_ptr p;    // pointer to an int
    Item_ptr ps; // pointer to an Item
};

int  main() {
    
    Item_ptr psv = malloc(sizeof(Item)); // allocate memory for an Item and put that address in psv - it has type Item_ptr;

    if (psv == NULL) {
        printf("Malloc failed\n");
    }
    printf("Malloc Allocated \n");

    psv->p;
    psv->ps;

    free(psv);

    return 0;
}
When you do this (use typedef to define a struct alias and struct pointer alias) you almost eliminate the need to declare things with '*', this is very very helpful when you have pointers to pointers as the code can become bewildering sometimes, especially if it has a subtle bug.

You can see I even defined one for Int_ptr, so wherever we need to declare an int * we can now just use Int_ptr, this gets rid of the * syntax and emphasizes that it's a pointer because of the _ptr name in the type.

This is 100% standard C.

I've used this on two very large code bases, one was a compiler for the PL/I language written in C for Windows and the other was sophisticated shared memory management API written in C, also for Windows. The source code is very clear and easy to read but would have been quite messy looking without this.
 

Papabravo

Joined Feb 24, 2006
21,225
The length of a pointer is not always four bytes -- increasingly most compilers in use are targeting 64-bit architectures and most (not all) of those use 8-bit pointers.
Yes, but whatever the length of a pointer is the example can be adjusted to that fact. It is even possible for pointers to be of different lengths if the architecture supports multiple pointer types.
 
Top