c - valgrind - 大小为 1 的无效读取地址 0x0 在 execlp 期间未进行堆栈、分配或(最近)释放

标签 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] 复制到已分配的程序中会出现问题。

#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:已修复,我没有测试是否给出了任何参数。

最佳答案

sizeof 并没有像你想象的那样做。变化:

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

至:

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

注释:

关于c - valgrind - 大小为 1 的无效读取地址 0x0 在 execlp 期间未进行堆栈、分配或(最近)释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44215184/

相关文章:

c - 如何创建一个 (C) 函数来使用 'read' 将文件中的数据读取到链接列表中?

c - 输入后 Char 指针(字符串)数组崩溃?

c - 内存泄漏 - g_strndup

Valgrind 适用于 macOS Mojave 10.14.2?还有其他选择吗?

c - c中有P2P框架吗?

c - 从文件中读取数据并将其写入链表

c - 创建服务器/客户端 TCP/IP 程序时遇到问题

c Valgrind 大小 4 的读取无效 -> 段错误

c - 类似于 scanf 的函数中的内存泄漏问题

c - Valgrind 无效写入错误,包含指向结构的指针数组