如何计算管道读数的c结构的大小?
How to calculate size of a structure in c for pipe reading?
一个结构s1
,其中包含几个另一个结构s2
和s2
-s1_length
的数量。 s2
包括一组int-arr
及其长度-s2_length
。我想在子进程中将 s1
写入管道并在父进程中读取它。但我一直得到 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_length
、s2_length_arr
、'sum'正常,但读取s
和segmentation fault
失败。有谁知道这里出了什么问题?非常感谢。
通常,您最好将 serialization/deserialization 代码与计算代码分开,将其放在单独的读写函数中。所以你可能有这样的东西:
// 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
函数来释放由 read_s1
分配的内存
您通常最终会希望程序中的每个结构类型都有一个 read_
、write_
和 free_
(可能还有 create_
)函数。您还可以通过标准化类型大小和字节顺序来做一些事情,以允许在具有不同体系结构的不同机器之间通信数据结构。
一个结构s1
,其中包含几个另一个结构s2
和s2
-s1_length
的数量。 s2
包括一组int-arr
及其长度-s2_length
。我想在子进程中将 s1
写入管道并在父进程中读取它。但我一直得到 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_length
、s2_length_arr
、'sum'正常,但读取s
和segmentation fault
失败。有谁知道这里出了什么问题?非常感谢。
通常,您最好将 serialization/deserialization 代码与计算代码分开,将其放在单独的读写函数中。所以你可能有这样的东西:
// 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
函数来释放由 read_s1
您通常最终会希望程序中的每个结构类型都有一个 read_
、write_
和 free_
(可能还有 create_
)函数。您还可以通过标准化类型大小和字节顺序来做一些事情,以允许在具有不同体系结构的不同机器之间通信数据结构。