Peter
Peter

Reputation: 33

pointer to an array boundary problem

I am programming in C. I am using also a library to create tasks which can communicate among them via messages. The content of these messages must be the pointer to the data you want to exchange.

In my case I want to send an array so I am sending a pointer to the array. In the receiving task I can then access the different elements by increasing the pointer, but, is there a way to know how long the array was?

Thank you in advance.

Upvotes: 3

Views: 202

Answers (5)

Genís
Genís

Reputation: 1508

Couldn't you use some kind of sentry value at the end of the buffers where the messages are stored. That should be such a value that you won't find it anywhere in the message. Depending on the type of these message its possible that there is such a value: typically a negative number if your messages consists of positive integers, a "INF" or "BIG_INT" number, etc. Then, you must process your message just up to the sentry value. Something like this:

#include <stdlib.h>
#include <string.h>
#define N 100
#define ENDTAG  -999999

void foo( int *arr ){
   int i = 0;
   while( arr[i] != ENDTAG ){
   //do whatever
   i++;
 }
}

int main( void ){
   int *arr = (int *) malloc( sizeof(int) * N );
  //fill the array, no matter how.
  //  ... 
  //set the sentry value
  arr[N-1] = ENDTAG;
  foo( arr );
  free( arr );
  return 0;
}

It may sound to much simple, but I actually used something like that more than once. You must though be absolutely sure that you'll take some restricted types of messages.

Upvotes: 0

cnicutar
cnicutar

Reputation: 182694

No, there is no way to do this as arrays decay to pointers when passed to functions, thus all information regarding size is lost.

  • You can include another parameter to specify the array length

    void func(int len, int arr[]);
    
  • You can mark the end of the array with a special value (perhaps like argv does)

  • You can put your array into a structure and pass that (and suffer the performance penalties) or pass the a pointer to the structure

    struct args {
        int arr[100];
    };
    

If you decide to go the first route, you can use a nice feature of C99, even if it doesn't actually enforce that arr has at least len elements:

void func(int len, int arr[len]);

Upvotes: 2

josh
josh

Reputation: 14443

No, you can't. The compiler doesn't know what the pointer is pointing to. You either need to pass the length value along with the array or you can trick it by allocating extra memory in order to store the length value before the start of the array.

Upvotes: 1

Constantinius
Constantinius

Reputation: 35069

No, that is not possible unless you also send the size of the array or set a guardian value in the end of the array.

I suggest that you do not send the array directly but use a intermediary struct, like the following:

struct intermediary {
    int *the_array; /* the pointer to the array */
    size_t size; /* the array size */
};

In the message you send the struct, and not the array itself.

Upvotes: 0

PP.
PP.

Reputation: 10864

No. So consider something slightly different.

struct arrayinfo {
    struct element *array;
    int count;
};

Then you can pass a pointer to your struct arrayinfo type and your receiving task will know how many elements are in your array.

An alternative technique is to make your array and array of pointers. Make your array one element bigger than necessary and set the last element to NULL.

Upvotes: 1

Related Questions