2017-05-27 94 views
0

我需要制作一个程序,用execlp调用一个新程序,然后将其输出发送回主程序将输出并将其修改为标准输出。 作为程序它工作得很好,但是当我测试它的valgrind它给了我:valgrind - 无效的读取大小1地址0x0不堆栈,malloc'd或(最近)在execlp期间释放

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

错误行是:strcpy(program,argv[optind]); 我不`吨知道为什么是一个问题,如果我复制的argv [OPTIND ]进入了一个被搅拌的程序。

#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:固定,如果任何参数给予我没有测试。

+0

你如何运行程序? – ks1322

+0

在我的电脑上用gcc然后./ 学校我不知道我只是上传它们的页面 –

+0

“程序工作” - >“程序*似乎工作*”。许多错误是潜在的。并非所有未定义行为都立即显现。 –

回答

0

sizeof不会做你认为它做的事。变化:

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

到:

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

注:

+0

char * program = malloc(strlen(argv [optind])+ 1)valgrind在strlen中发现了一个问题。 == 14085 ==大小为1的无效读取 == 14085 ==在0x4C2E0E2:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) –

+0

我猜你没有提供任何命令行参数,所以'argv [optind]'可能是无效的。您的代码应该对所需的参数进行完整性检查,并且如果它们不存在,请妥善退出。 –

+0

是的!情况就是这样,我只是在个人电脑上进行测试,但学校做了一个空白测试。谢谢 –

相关问题