使用write函数时,获取未初始化字节的valgrind错误

时间:2016-12-06 14:11:16

标签: c linux memory pipe valgrind

我的程序应该与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);
}

有人可以帮我解决这个问题吗?
感谢您的时间和精力,

Domen

1 个答案:

答案 0 :(得分:0)

此:

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

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

解决方案是捕获返回值以了解多少:

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

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