首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >valgrind -在execlp过程中,对大小为1的地址0x0的无效读取未进行堆栈、错误锁定或(最近)释放

valgrind -在execlp过程中,对大小为1的地址0x0的无效读取未进行堆栈、错误锁定或(最近)释放
EN

Stack Overflow用户
提问于 2017-05-27 17:26:14
回答 1查看 382关注 0票数 0

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

代码语言:javascript
复制
Invalid read of size 1 
Address 0x0 is not stack'd, malloc'd or (recently) free'd

错误行是:strcpy(program,argv[optind]);我不知道为什么我把argvoptind复制到错误的程序中会有问题。

代码语言:javascript
复制
#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:我还注意到我的学校页面上的测试程序是这样说的:

代码语言:javascript
复制
    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 

但是这个程序在我的pc上运行和编译都很好。已修复添加#include <getopt.h>时出现的此问题

getopt issue

PS:修复了,我没有测试是否给出了任何参数。

EN

回答 1

Stack Overflow用户

发布于 2017-05-27 17:31:43

sizeof并不像您认为的那样工作。更改:

代码语言:javascript
复制
char* program = (char*)malloc(sizeof(argv[optind]));

至:

代码语言:javascript
复制
char* program = malloc(strlen(argv[optind]) + 1);

备注:

对于string terminator

  • redundant and potentially dangerous cast removed

  • 使用strlen,而不是1
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44215184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档