0
struct student
{
   int roll;
   char *name;
};

int main()
{
  int i;
  struct student arr[2];
  arr[0].roll = 12;
  arr[1].name = "John";

  arr[1].roll = 13;
  arr[1].name = "Craig";

  struct student *ptr;

  ptr=arr;

  // This is perfect.

  for(i = 0; i<2; i++)
  {
    printf("%d %s", ptr->roll, ptr->name);
  }

  // This is also ok.
   printf("%d %s", ptr->roll, ptr->name);

   ptr++ // getting to next structure.

   printf("%d %s", ptr->roll, ptr->name);

  // But this isn't ok

  while(*ptr || ptr->name != NULL)
  {
    ptr++;
  }

  return 0;
}

How to check pointer in while loop?

1
  • 1
    ptr points to an array if you increment it, ptr start pointing to a memory out size array Commented Sep 20, 2013 at 7:01

4 Answers 4

4

ptr points to an array if you increment it, ptr start pointing to a memory out size array that is not null. You can do something like:

ptr = arr;
while (ptr <  (arr +  sizeof(arr)/sizeof(arr[0])) ){
   ptr++;
}

Note: this technique will nnot work for dynamic arrays.

To learn what is this formula about read: Weird behavior when printing array in C?

Sign up to request clarification or add additional context in comments.

8 Comments

Yes, but why this is running an extra loop, even this was the same case when i did while(ptr->name != NULL) i.e an extra garbage value
@user1502952 Why extra? my answer is about how to save ptr not pointing to outside array that is actually undefined behavior. Suppose if if for some arr index value name points to a NULL then add an extra check.
@user1502952 do like: while (ptr < (arr + sizeof(arr)/sizeof(arr[0]) -1) && ptr->name != NULL ){ do your code here}
Why -1? I fail to see why this is necassary - it even seems invalid! It'll skip last element. For 1 element in an array it will not iterate at all.
@Dariusz Math mathematically I may be uncorrected here, Should I remove ?
|
2

You can use ptr check for null if you traversing an array of pointers AND when you know that the end of such array is marked with NULL. You are not.

You actually are traversing an array of structures with the ptr pointing straight to the memory location of the first element.

You have to keep track of the size of the array (or amount of its filled elements) and just stop after you have gone through them all.

int count = 2;
struct student arr[count];
struct student* ptr = arr;

for (int i=0; i<count; i++) { 
  // do your stuff

  ptr++; // place it in for if you like
}

1 Comment

I guess it easier! then my answer.
1

You can use this:

struct student *ptr=arr;
int max_len = sizeof(arr)/sizeof(*arr);
while(max_len--)
{
    //do something...
    ptr++;
}

One more thing I want to point out is you need to allocate memory for the char* pointer before allocating it with a string.The last loop which you have written doesn't execute at all, since all are NULL pointers.

Other way around is to put some special value in the roll number(say a negative value) of the last struct in the array. You then traverse the array until the roll number is positive. Note that this method can also be used for dynamic arrays.

struct student *arr = (struct student*)malloc(20*sizeof(struct student));
*(arr+19).roll = -1; //this acts as a sentinel to indicate the end of the array....
struct student *ptr=arr;
while(ptr->roll > 0)
{
      //do something...
      ptr++;
}

3 Comments

Yes an extra garbage value.
I don't get why there will be a garbage value. Both the loops traverse until the end of array and stop.
that is perfect the only point is to take fixed size array, i hadn't done that done at the point of checking(arr[2]).
0
while(*ptr || ptr->name != NULL)

First things first: the value of *ptr is a struct, which can't be converted to a boolean value and so while(*ptr) won't compile.

In order to null-terminate an array of structs, you must choose some struct member which you know will never be NULL when the struct is initialized (usually an important pointer), and use it as the flag. You do have that: the name field.

while(ptr->name != NULL)

Then the only problem is that your array isn't actually NULL terminated. You need to reserve an extra, third element at the end, just like with strings. An easy way to do so is by zero-initializing the whole array at declaration. So:

struct student arr[3] = {0};
arr[0].roll = 12;
arr[0].name = "John";
...

Which would have the same effect as manually setting ar[2].name = NULL;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.