簡體   English   中英

如何為 pipe 讀數計算 c 中結構的大小?

[英]How to calculate size of a structure in c for pipe reading?

一個結構體s1里面包含了另外幾個結構體s2s2的個數s1_length s2包括一組 int- arr及其長度 - s2_length 我想在子進程中將s1寫入 pipe 並在父進程中讀取它。 但是我總是遇到segmentation falut 我猜計算結構s1的大小有問題。 但是我真的找不到那里到底錯在哪里。

我的代碼是這樣的:

struct s1{
 int s1_length;
 struct s2 *s2;
};

struct s2{
 int s2_length;
 int *arr;
};

int getSize(int s_length, int *s2_length_arr){
    int i, sum = 0;
    for(i=0; i< s.length; i++){
        sum += sizeof(int) * (arr_length[i] + 1);
    }
    sum += sizeof(int);
    return sum;
}

void main(){
    ...
    int i;
    int *fds = malloc(sizeof(int) * 10 *2);

    for(i=0; i<10; i++)
        pipe(fds +i*2);

    struct s1 s;
    struct s2 ss;
    s.s1_length = 0;
    int s_size, sum;
    int *s2_length_arr;

    for(int i=0; i<10; i++){
       child_pid = fork();
       if(child_pid == 0){
           close(fds[i*2]);

           // do something
           // return `s1` include 10 `s2`
           s = getS(...);

           // return a int array, with the length of `arr` of every `s2`
           s2_length_arr = getS2LengthArray(...);
           sum = getSize(s.length, s2_length_arr);

           write(fds[i*2+1], &s_length, sizeof(int));
           write(fds[i*2+1], &s2_length_arr, sizeof(int)*s_length);
           write(fds[i*2+1], &s, sum);
           close(fds[i*2+1]);
           exit(0);
       } 
    for(int i=0; i<10; i++){
       close(fds[i*2+1]);
       read(fds[i*2], &s_length, sizeof(int));
       read(fds[i*2], &s2_length_arr, sizeof(int) * s_length);
       struct s1 s;
       s.s2 = malloc(sizeof(struct s2) * s_length);
       for(j=0; j<s_length; j++)
           s.s2[j].arr = malloc(sizeof(int) * s2_length_arr[j]);
       read(fds[i*2], &s, sum);
       close(fds[i*2]);
    }
}

結果讀取s_lengths2_length_arr和'sum'都正常,但是讀取s失敗, segmentation fault 有誰知道這里出了什么問題? 非常感謝。

通常,您最好將序列化/反序列化代碼與計算代碼分開,將其放在單獨的讀寫函數中。 所以你可能有類似的東西:

// read/write checking for errors
void read_check(int fd, void *buffer, size_t len) {
    char *p = buffer;
    while (len > 0) {
        size_t rlen = read(fd, p, len);
        if (rlen <= 0) {
            fprintf(stderr, "Unexpected error/eof reading from %d\n", fd);
            exit(1); }
        p += rlen;
        len -= rlen }
}
void write_check(int fd, void *buffer, size_t len) {
    char *p = buffer;
    while (len > 0) {
        size_t wlen = write(fd, p, len);
        if (wlen <= 0) {
            fprintf(stderr, "Unexpected error/eof writing to %d", fd);
            exit(1); }
        p += wlen;
        len -= wlen; }
}

struct s1{
    int s1_length;
    struct s2 *s2;
};

struct s2{
    int s2_length;
    int *arr;
};

void write_s2(int fd, struct s2 *p) {
    write_check(fd, &p->s2_length, sizeof(p->s2_length));
    write_check(fd, p->arr, p->s2_length * sizeof(*p->arr));
}
void write_s1(int fd, struct s1 *p) {
    write_check(fd, &p->s1_length, sizeof(p->s1_length));
    for (int i = 0; i < p->s1_length; ++i)
        write_s2(fd, &p->s2[i]);
}
void read_s2(int fd, struct s2 *p) {
    read_check(fd, &p->s2_length, sizeof(p->s2_length));
    p->arr = malloc(p->s2_length * sizeof(*p->arr));
    if (!p->arr) {
        fprintf(stderr, "ran out of memory\n");
        exit(1); }
    read_check(fd, p->arr, p->s2_length * sizeof(*p->arr));
}
void read_s1(int fd, struct s1 *p) {
    read_check(fd, &p->s1_length, sizeof(p->s1_length));
    p->s2 = malloc(p->s1_length * sizeof(*p->s2));
    if (!p->s2) {
        fprintf(stderr, "ran out of memory\n");
        exit(1); }
    for (int i = 0; i < p->s1_length; ++i)
        read_s2(fd, &p->s2[i]);
}

然后你只需在孩子中調用write_s1來寫入整個鏈接的數據結構,並在父級中調用read_s1來讀回它。 你可能還想寫一個free_s1 function 來釋放 read_s1 分配的read_s1

對於程序中的每個結構類型,您通常最終都需要一個read_write_free_ (可能還有create_ ) function 。 您還可以通過標准化類型大小和字節順序來做一些事情,以允許在具有不同體系結構的不同機器之間通信數據結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM