указатель на границу задачи массива - PullRequest
2 голосов
/ 24 августа 2011

Я программирую на C. Я также использую библиотеку для создания задач, которые могут общаться между ними посредством сообщений. Содержимое этих сообщений должно быть указателем на данные, которые вы хотите обменять.

В моем случае я хочу отправить массив, поэтому я посылаю указатель на массив. В получающей задаче я могу затем получить доступ к различным элементам, увеличив указатель, но есть ли способ узнать, как долго длился массив?

Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 24 августа 2011

Нет, это невозможно, так как массивы распадаются на указатели при передаче в функции, поэтому вся информация о размере теряется.

  • Вы можете включить другой параметр, чтобы указать длину массива

    void func(int len, int arr[]);
    
  • Вы можете пометить конец массива специальным значением (возможно, как argv делает)

  • Вы можете поместить свой массив в структуру и передать его (и понести потери производительности ) или передать указатель на структуру

    struct args {
        int arr[100];
    };
    

Если вы решите пойти по первому маршруту, вы можете использовать симпатичную функцию C99, даже если она фактически не обеспечивает, чтобы arr содержал хотя бы len элементов:

void func(int len, int arr[len]);
1 голос
/ 24 августа 2011

Нет, вы не можете. Компилятор не знает, на что указывает указатель. Вам либо нужно передать значение длины вместе с массивом, либо вы можете обмануть его, выделив дополнительную память для хранения значения длины до начала массива.

0 голосов
/ 24 августа 2011

Не могли бы вы использовать какое-то значение часового в конце буферов, где хранятся сообщения. Это должно быть таким значением, что вы не найдете его нигде в сообщении. В зависимости от типа этих сообщений возможно наличие такого значения: обычно это отрицательное число, если ваши сообщения состоят из натуральных чисел, числа «INF» или «BIG_INT» и т. Д. Затем вы должны обработать ваше сообщение до часовая стоимость. Примерно так:

#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;
}

Это может звучать очень просто, но я действительно использовал нечто подобное не раз. Тем не менее, вы должны быть абсолютно уверены, что будете принимать ограниченные типы сообщений.

0 голосов
/ 24 августа 2011

Нет, это невозможно, пока вы не отправите размер массива или не установите значение хранителя в конце массива.

Я предлагаю не отправлять массив напрямую, а использовать посредника.struct, как показано ниже:

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

В сообщении вы отправляете структуру, а не сам массив.

0 голосов
/ 24 августа 2011

Нет. Итак, рассмотрим что-то немного другое.

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

Затем вы можете передать указатель на ваш тип struct arrayinfo, и ваша задача-получатель узнает, сколько элементов в вашем массиве.

Альтернативный метод - создать массив и массив указателей. Сделайте ваш массив на один элемент больше необходимого и установите для последнего элемента значение NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...