使用写函数时出现未初始化字节的 valgrind 错误

Getting valgrind error for uninitialised bytes when using write function

我的程序应该与 4 个子进程之间的管道进行通信。该程序可以运行,但是当使用 valgrind 检查程序时,我收到有关 char 缓冲区的错误,但程序结束并打印出正确答案。这是错误:

终端命令:./prodajnaVerigaAnon 100

==12926== Syscall param write(buf) points to uninitialised byte(s)
==12926==    at 0x4F22710: __write_nocancel (syscall-template.S:81)
==12926==    by 0x400B4E: main (prodajnaVerigaAnon.c:45)
==12926==  Address 0xfff0007e4 is on thread 1's stack
==12926==  in frame #1, created by main (prodajnaVerigaAnon.c:9)
==12926== 
==12927== Syscall param write(buf) points to uninitialised byte(s)
==12927==    at 0x4F22710: __write_nocancel (syscall-template.S:81)
==12927==    by 0x400CCF: main (prodajnaVerigaAnon.c:68)
==12927==  Address 0xfff0007e4 is on thread 1's stack
==12927==  in frame #1, created by main (prodajnaVerigaAnon.c:9)
==12927== 
==12928== Syscall param write(buf) points to uninitialised byte(s)
==12928==    at 0x4F22710: __write_nocancel (syscall-template.S:81)
==12928==    by 0x400E58: main (prodajnaVerigaAnon.c:92)
==12928==  Address 0xfff0007e4 is on thread 1's stack
==12928==  in frame #1, created by main (prodajnaVerigaAnon.c:9)
==12928== 
156

程序代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char* argv[])
{
        int size = 80;
        int fd1[2];
        int fd2[2];
        int fd3[2];
        char readbuffer[size];

        if(argc > 1) {

            if(pipe(fd1) == -1) {
                perror("tezava pri odpiranju cevi 1");
                return -1;
            }
            if(pipe(fd2) == -1) {
                perror("tezava pri odpiranju cevi 2");
                return -1;
            }
            if(pipe(fd3) == -1) {
                perror("tezava pri odpiranju cevi 3");
                return -1;
            }

            for(int i=0;i<4;i++) {
                if(i==0) {
                    switch(fork()) {
                        case 0:
                            close(fd1[0]);

                            close(fd2[0]); 
                            close(fd2[1]);
                            close(fd3[0]);
                            close(fd3[1]);
                            for(int i=1;i<argc;i++) {
                                char init_price[size];
                                sprintf(init_price,"%d",atoi(argv[i]));
                                write(fd1[1], init_price, size);
                            }
                            close(fd1[1]);
                            _exit(0);

                    }
                }
                else if(i == 1) {
                    switch(fork()) {
                        case 0:
                            close(fd1[1]);

                            close(fd2[0]); 
                            close(fd3[0]);
                            close(fd3[1]);
                            for(int i=1;i<argc;i++) {
                                read(fd1[0], readbuffer, sizeof(readbuffer));
                                int tmp_price = atoi(readbuffer);
                                int fifth_of_price = tmp_price / 5;
                                tmp_price = tmp_price + fifth_of_price;
                                char buffer[size];
                                sprintf(buffer,"%d",tmp_price);
                                write(fd2[1],buffer,size);
                            }

                            close(fd2[1]);
                            close(fd1[0]);
                            _exit(0);
                    }
                }
                else if(i == 2) {
                    switch(fork()) {
                        case 0:
                            close(fd2[1]);

                            close(fd3[0]);
                            close(fd1[0]);
                            close(fd1[1]);

                            for(int i=1;i<argc;i++) {
                                read(fd2[0],readbuffer,sizeof(readbuffer));
                                int tmp_price = atoi(readbuffer);
                                int third_of_price = tmp_price * 0.3f;
                                tmp_price = tmp_price + third_of_price;
                                char buffer[size];
                                sprintf(buffer,"%d",tmp_price);
                                write(fd3[1],buffer,size);
                            }
                            close(fd3[1]);
                            close(fd2[0]);
                            _exit(0);
                    }
                }
                else if(i == 3) {
                    switch(fork()) {
                        case 0:
                            close(fd3[1]);

                            close(fd1[0]);
                            close(fd1[1]);
                            close(fd2[0]);
                            close(fd2[1]);
                            for(int i=1;i<argc;i++) {
                                read(fd3[0],readbuffer,sizeof(readbuffer));
                                printf("%s ",readbuffer);
                                fflush(stdout);
                            }
                            printf("\n");
                            close(fd3[0]);
                            _exit(0);

                    }
                }
            }

            close(fd1[0]); 
            close(fd1[1]);
            close(fd2[0]);
            close(fd2[1]);
            close(fd3[0]);
            close(fd3[1]);

            for(int i=0;i<4;i++) {
                wait(NULL);
            }


        }
        else {
            printf("Missing input arguments. Usage:\n./prodajnaVerigaAnon <price 1> <price 2> ... <price n>\n");
        }
        return(0);
}

谁能帮我解决这个问题?
感谢您的时间和精力,

多门

这个:

sprintf(init_price,"%d",atoi(argv[i]));
write(fd1[1], init_price, size);

是错误的,它将缓冲区的完整大小 size 传递给 write,但只有前几个字符会被 sprintf() 写入。

解决方案是捕获return值以知道有多少:

const int len = sprintf(init_price, "%d", atoi(argv[i]));
write(fd1[1], init_price, (size_t) len);

如果您需要 0 终止符,请改为使用最后一个参数 (size_t) len + 1