Your program behaviour is undefined because it end up dereferencing a NULL pointer here:
int *p = NULL;
int h[] = {1,2,3,4,5,1,1,3,4};
j = count(h, p , sizeof(h)/sizeof(int) , 1);
printf("%d %d", *p,j);
^^
|
Dereferencing p which is a NULL pointer
The way you are passing the p pointer from main() function to count() function, you are passing NULL. That means, in context of your program, this
j = count(h, p , sizeof(h)/sizeof(int) , 1);
is equivalent to this
j = count(h, NULL , sizeof(h)/sizeof(int) , 1);
The count() function parameter p will receive NULL as argument i.e. it's equivalent to p = NULL (where p is count() function parameter).
Whatever you assign to p in count() function, you are actually modifying a local variable of count() function. No changes are going to reflect in pointer variable p of main() function and it will remain a NULL pointer.
Now, lets come to the count() function.
In this snip of code of count() function:
for(int i=0; i<size ;i++)
{
if(h[i]==d && bool == 0)
{
j++;
bool = 1;
p = &i;
}
else if(h[i]==d)
j++;
}
the scope and life of loop variable i is within the for loop block. Once, the loop exit the lifetime of i is ended. JFYI - accessing an object outside of its lifetime is undefined behaviour. So, if p hold &i and out of loop body if your program access p then it will lead to undefined behaviour. Also, *p=-1; statement in count() will also lead to undefined behaviour because, in count() function p will be a NULL pointer if bool==0.
Remember, if a function is passing a pointer to another function as a argument and expecting that function to modify the value of pointer, which it receive as parameter, then the pointer should be pointing to a valid memory location before the calling function access and modify it's memory contents or the caller function should pass address of pointer as argument and let the calling function allocate memory dynamically to it so that it should be accessible from the caller function as well (which is main() function, in your case).
There are couple ways to achieve this.
Method I:
Pass a valid memory location to calling function.
Either pass address of a local variable of caller function as argument (this is same as your second code snippet)
int main (void) {
int j;
size_t res = 0;
size_t *p = &res; // p is pointing to res variable
int h[] = {1, 2, 3, 4, 5, 1, 1, 3, 4};
int num = 1;
j = count (h, p, sizeof (h) / sizeof (int), num);
if (j != -1) {
printf ("%zu %d", *p, j);
} else {
printf ("%d not found\n", num);
}
return 0;
}
Or allocate memory to pointer in caller function and pass it
int main (void)
{
int j;
size_t *p = NULL;
int h[] = {1, 2, 3, 4, 5, 1, 1, 3, 4};
int num = 1;
p = malloc (sizeof (size_t));
if (p == NULL) {
fprintf (stderr, "Failed to allocate memory");
exit (EXIT_FAILURE); // or whatever you want to do in case of allocation failure
}
j = count (h, p, sizeof (h) / sizeof (int), num);
if (j != -1) {
printf ("%zu %d", *p, j);
} else {
printf ("%d not found\n", num);
}
free(p);
return 0;
}
and the count() function implementation for both the above cases:
int count (int h[], size_t *p, size_t size, int d) {
int j = 0;
for (size_t i = 0; i < size ; ++i) {
if(h[i] == d) {
if (j == 0) {
*p = i;
}
++j;
}
}
return j == 0 ? -1 : j;
}
Method II:
Pass the address of p and dynamically allocate memory to p in count() function before accessing it. Note that, objects with allocated storage duration live until they are destroyed by a call to free(). So, if count() function allocates memory to a pointer, whose address passed as argument to count() function from main() function, then that memory will be accessible in main() function as well via pointer variable p.
#include <stdio.h>
#include <stdlib.h>
int count (int h[], size_t **p, size_t size, int d) {
int j = 0;
for(size_t i = 0; i < size ; ++i) {
if(h[i] == d) {
if ((j == 0) && (p != NULL)) {
*p = malloc (sizeof (size_t));
if (p == NULL) {
fprintf (stderr, "Failed to allocate memory");
exit (EXIT_FAILURE);
}
**p = i;
}
++j;
}
}
return j == 0 ? -1 : j;
}
int main (void) {
int retval;
size_t *p = NULL;
int h[] = {1, 2, 3, 4, 5, 1, 1, 3, 4};
int num = 3;
retval = count (h, &p, sizeof (h) / sizeof (int), num);
if (retval != -1) {
printf ("%zu %d\n", *p, retval);
} else {
printf ("%d not found\n", num);
}
// free memory once you are done with it
if (p != NULL) {
free (p);
}
return 0;
}
Additional:
- Using
void as return type of main function is not as per standards. The return type of main function should be int.