0

given an array lets say, char *words[] = {"The", "Quick", "Brown", "Fox", "Jumped", "Over", "The", "Lazy", "Dog"}; and a pointer char ** point = &word[9]; without knowing the size of the array inputed, how would you be able to bring the pointer to the start of the array? The purpose of this is to use in a recursive function where a pointer is set at the start of the array but as the function recurses, the pointer is incremented each time it recurses.

I've tried simply decrementing the pointer until I hit a null pointer at the start but the pointer points to some random value in memory past the array. Any advice on how to approach this?

undertaker
  • 17
  • 5

3 Answers3

4

In general, there is no way of knowing the size of an array given only a pointer to one of its elements; you have to keep track of it yourself.

Either keep a pointer to the start of the array, or put some sentinel value (like a NULL pointer) there yourself.

Ture Pålsson
  • 6,088
  • 2
  • 12
  • 15
0

You can't. A pointer is nothing more or less than an address in memory. A simple number. The start of the array is at a different address in memory, another simple number.

For instance, your array might start at the memory address 12608 (= any possible number except 0), and the last element of it would be at address 12680. You don't know what is stored either at address 12600 or 12688. If you access either of these addresses, anything might happen from silent data corruption, over an immediate crash, up to and including some bad guy downloading a backdoor onto your PC.

As such, it is your job to ensure that your program does not access any arrays out-of-bounds. It is your job to ensure that you know the size and starting address of the array at any point where you need them, and it is your job to ensure that all accesses are within these limits.

Now, for a statically allocated array like the one in your example, you can take its size by using the sizeof operator:

size_t wordCount = sizeof(words)/sizeof(*words);
printf("this should be 9 in your example: %zu\n", wordCount);

This takes the number of bytes used for the array words, and divides it by the number of bytes in the first element of the array *words. It's the standard trick to get the element count of static arrays.


However, that only works as long as words is actually an array of which the compiler knows the size. Once you pass it to a function, that information is gone:

void buggy(char* words[]) {
    printf("not what you expect: %zu\n", sizeof(words)/sizeof(*words));
}

The reason is, that arrays decay into pointers when you pass them to a function, and a pointer is only a single number that does not retain any size information of the array. That information was only in the array's type, and that type has decayed away.

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106
  • [Pointers are not simple numbers.](https://stackoverflow.com/a/11714314/298225) – Eric Postpischil Nov 26 '21 at 12:17
  • @EricPostpischil That's the language lawyer point of view. But it's neither helpful for understanding, nor does it have anything to do with the real machine code that your compiler emits for a real physical machine. To all relevant CPUs in use today, a data pointer is nothing but a simple number. – cmaster - reinstate monica Nov 26 '21 at 13:28
  • A reason it is not a number and that the machine code is not controlling is that modern compilers do not directly generate machine code. They analyze source code semantically and optimize it. When a pointer is treated as a “simple number” rather than used in accordance with the C standard rules, it may result in undefined behavior in various ways. Telling students pointers are numbers leads to bugs in their code. – Eric Postpischil Nov 26 '21 at 18:24
-1

you can get the size of the array using :

printf("length of the array : %d \n", sizeof(words)/8);

See sample below.

int main()
{

  char *words[] = {"The", "Quick", "Brown", "Fox", "Jumped", "Over", "The", "Lazy", "Dog"};
  char ** point = &words[9];
  int i;
  printf("length of the array : %d \n", sizeof(words)/8);

  for(i=0;i<9;i++){
    printf("%s\n",words[i]);
  }


  for(i=0;i<9;i++){
   printf("%d\n",point[i]);
  }
  return 0;
}

and then, you can loop through using size of the array.