Написание и чтение структуры с динамическим массивом через канал в C - PullRequest
3 голосов
/ 24 марта 2010

У меня есть структура с динамическим массивом внутри:

struct mystruct {
 int count;
 int *arr;
} mystruct_t;

и я хочу передать эту структуру по каналу в C и вокруг кольца процессов. Когда я изменяю значение count в каждом процессе, оно изменяется правильно. Моя проблема с динамическим массивом.

Я выделяю массив следующим образом:

mystruct_t x;
x.arr = malloc( howManyItemsDoINeedToStore * sizeof( int ) );

Каждый процесс должен читать из канала, что-то делать с этим массивом, а затем записывать это в другой канал. Кольцо настроено правильно; Там нет проблем. Моя проблема в том, что все процессы, кроме первого, не получают правильную копию массива. Я инициализирую все значения, скажем, 10 в первом процессе; тем не менее, все они отображаются как 0 в следующих.

for( j = 0; j < howManyItemsDoINeedToStore; j++ ){
    x.arr[j] = 10;
}

Вход:

Initally:       10      10      10      10      10
After Proc 1:   9       10      10      10      15
After Proc 2:   0       0       0       0       0
After Proc 3:   0       0       0       0       0
After Proc 4:   0       0       0       0       0
After Proc 5:   0       0       0       0       0
After Proc 1:   9       10      10      10      15
After Proc 2:   0       0       0       0       0
After Proc 3:   0       0       0       0       0
After Proc 4:   0       0       0       0       0
After Proc 5:   0       0       0       0       0

Теперь, если я изменю свой код, скажем, на

struct mystruct {
 int count;
 int arr[10];
} mystruct_t;

все правильно передается по трубе, нет проблем. Я использую read и write в C:

write( STDOUT_FILENO, &x, sizeof( mystruct_t ) );
read( STDIN_FILENO, &x, sizeof( mystruct_t ) );

Ответы [ 3 ]

1 голос
/ 24 марта 2010

В динамическом случае ваша структура не содержит сам массив, просто указатель на него. (Если вы проверите sizeof (mystruct_t), вы увидите, что он достаточно большой, чтобы содержать int и указатель).

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

Если вы хотите скопировать массив переменного размера, вам придется выполнить 2 операции записи: первая запишет mystruct.count, а вторая - массив целых чисел.

1 голос
/ 24 марта 2010

Когда вы выделяете динамический массив, функция malloc возвращает указатель на область памяти, которой нет в вашей структуре. Взгляните на пример:

0x0000000F int count
0x00000014 >> pointer to your array elsewhere 0x000000F0


0x000000F0 your array is here

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

struct mystruct{
  int count;
  int *arr;
  char pad [5];
}mystruct_t;
mystruct_t x;
x.pad={0x5b,0x5C,0x5D,0x5E,0x5F};
1 голос
/ 24 марта 2010

Вы пишете только структуру. Если вы хотите передать массив целых чисел, вы должны будете также записать это в канал. Вот почему ваш второй вариант работает, так как массив указан как часть структуры.

...