valgrind - 大小为1的读取无效地址0x0不是堆栈' d,malloc&d; dd或(最近)在execlp期间释放

时间:2017-05-27 09:26:14

标签: c valgrind

我需要创建一个用execlp调用新程序的程序,然后将其输出发送回主程序,该程序将输出并修改为标准输出。 至于程序它工作得很好但是当我用valgrind测试它时它给了我:

Invalid read of size 1 
Address 0x0 is not stack'd, malloc'd or (recently) free'd

错误行是:strcpy(program,argv[optind]); 如果我将argv [optind]复制到malloced的程序中,我不知道为什么会出现问题。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <wait.h>
#include <ctype.h>
#include <string.h>

int main(int argc, char** argv){

    int c,U=0,l=0,x=0,r=0;
    extern char *optarg;
    extern int optind;
    extern int optopt;
    while ( (c = getopt(argc, argv, ":Ulxr")) != -1) {
        switch (c) {
            case 'U': U = 1;
                      break;
            case 'l': l = 1;
                      break;
            case 'x': x = 1;
                      break;
            case 'r': r = 1;
                      break;
        }
    }
    char* program = (char*)malloc(sizeof(argv[optind]));
    strcpy(program,argv[optind]);
    int nov_stdin[2];
    int nov_stdout[2];
    if(pipe(nov_stdin)!=0){
        perror("tezava pri ustvarjanju cevi za stdin");
        return -1;
    }
    if(pipe(nov_stdout)!=0){
        perror("tezava pri ustvarjanju cevi za stdout");
        return -1;
    }
    int child_pid; // tukaj bomo hranili pid otroka, ki ga vrne fork
    switch(child_pid=fork()){
        case -1:
            perror("tezava pri klicu fork");
            return 0;

        case 0:
            close(nov_stdout[0]); // stdout zelimo pisati, zato zapremo branje
            dup2(nov_stdout[1], 1); // zapremo 1 in ga zamenjamo z nov_stdin[1]
            execlp(program, program, (char*)0);
            return 0;
    }
    free(program);
    close(nov_stdin[0]);
    close(nov_stdout[1]);
    char data;
    while(read(nov_stdout[0], &data, 1) > 0){
        if(l == 1){data = tolower(data);}
        if(U == 1){data = toupper(data);}
        if(r == 1){
            int new_data = (char)data;
            if(new_data == 10){
                data = ' ';
            }
        }
        if(x != 1){
        printf("%c", data);
        }else{
            if(isprint(data)){
                printf("%c", data);
            }else{
                printf("10");
            }
        }
    }
    printf("\n");
    wait(0);
    return 0;
}

感谢您的帮助。

PS:我也注意到我学校页面上的测试程序是这样说的:

    make clean all

rm -f main main.o
gcc -Wall -std=c99   -c -o main.o main.c
main.c: In function ‘main’:
main.c:19:5: warning: implicit declaration of function ‘getopt’ [-Wimplicit-function-declaration]
     while ( (c = getopt(argc, argv, ":Ulxr")) != -1) {
     ^
main.c:18:16: warning: unused variable ‘optopt’ [-Wunused-variable]
     extern int optopt;
                ^
main.c:16:18: warning: unused variable ‘optarg’ [-Wunused-variable]
     extern char *optarg;
                  ^
gcc -Wall -std=c99 main.o -o main 

但该程序在我的电脑上运行并编译得很好。 修复了添加#include <getopt.h>

的问题

getopt issue

PS:FIXED,我没有测试是否有任何论据。

1 个答案:

答案 0 :(得分:0)

sizeof没有按照您的想法行事。变化:

char* program = (char*)malloc(sizeof(argv[optind]));

为:

char* program = malloc(strlen(argv[optind]) + 1);

注意: