c: 将 malloc 的数组元素设置为 NULL(无效写入)

标签 c arrays process valgrind free

我正在处理并行进程,在我的代码的一部分中,我想 fork 一个新进程,该进程使用略有不同的参数调用同一程序。例如,如果用户最初调用“./prog arg1 arg2 arg3”,我想 fork 一个执行“./prog -n 1 arg2 arg3”的新进程,然后该程序将 fork 并执行“./prog - n 2 arg3。”我能想到的唯一方法是使用 execv(),但我遇到了问题,因为 execv 要求传递给它的 argv[] 数组中的最后一个元素为 NULL。下面是我的代码,我将在下面发布 valgrind 输出。

        //fork an additional process: ./prog -n (i+1) args...
        //  could accomplish by execv("./prog", paramlist), where paramlist is
        //      the same as -n (i+1) and then argv, skipping argv[1]

        //create new paramlist
        char **params = malloc(sizeof(char*) * argc + 2 );

        sprintf(numbuf, "%d", i+1);

        //./prog -n (i+1) argv[2:argc-1]
        params[0] = argv[0];
        params[1] = "-n";
        params[2] = numbuf;
        for(int i = 2; i<argc; i++){    //skip argv[0] bc we already assigned it
            params[i+1] = argv[i];      //skip argv[1] because we just worked on it

        }
        params[argc+1] = NULL;          //list must be null terminated

        pid3 = fork();
        if(0 == pid3){
            execv("./prog", params);
            exit(-1);
        }   //no waitpid here, because we'd like this process to continue on its own

        params[argc+1] = "";            //avoid invalid free
        free(params);

当我正常运行此代码时,出现以下错误:

*** Error in `./prog': free(): invalid next size (fast): 0x0000000001ac3830 ***

Valgrind 告诉我这个:

==28067== Memcheck, a memory error detector
==28067== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28067== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28067== Command: ./prog ./photos/photo1.jpg
==28067== 
=====Displaying photo 0 (be patient.. XQuartz sucks)
Enter degrees to rotate image(0,90,180,270): 90
Enter a caption > thumb
==28067== Invalid write of size 8
==28067==    at 0x400C58: main (in /usr/prog)
==28067==  Address 0x51fa8d0 is 16 bytes inside a block of size 18 alloc'd
==28067==    at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
==28067==    by 0x400C05: main (in /usr/prog)
==28067== 
==28067== Invalid write of size 8
==28067==    at 0x400CC3: main (in /usr/prog)
==28067==  Address 0x51fa8d8 is 6 bytes after a block of size 18 alloc'd
==28067==    at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
==28067==    by 0x400C05: main (in /usr/prog)
==28067== 
==28067== Invalid write of size 8
==28067==    at 0x400D0E: main (in /usr/prog)
==28067==  Address 0x51fa8d8 is 6 bytes after a block of size 18 alloc'd
==28067==    at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
==28067==    by 0x400C05: main (in /usr/prog)
==28067== 
==28071== Syscall param execve(argv) points to unaddressable byte(s)
==28071==    at 0x4F00CF7: execve (in /usr/lib64/libc-2.23.so)
==28071==    by 0x400CE8: main (in /usr/prog)
==28071==  Address 0x51fa8d2 is 0 bytes after a block of size 18 alloc'd
==28071==    at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
==28071==    by 0x400C05: main (in /usr/prog)
==28071== 
==28067== 
==28067== HEAP SUMMARY:
==28067==     in use at exit: 0 bytes in 0 blocks
==28067==   total heap usage: 5 allocs, 5 frees, 1,051,194 bytes allocated
==28067== 
==28067== All heap blocks were freed -- no leaks are possible
==28067== 
==28067== For counts of detected and suppressed errors, rerun with: -v
==28067== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

有趣的是,如果我注释掉“free(params)”行,则会出现段错误,出现在它之前的行“params[argc+1] = "";' .为什么会这样?

最佳答案

char **params = malloc(sizeof(char*) * argc + 2 );

应该是

char **params = malloc(sizeof(char*) * (argc + 2) );

关于c: 将 malloc 的数组元素设置为 NULL(无效写入),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39629409/

相关文章:

c - 如何将给定基数中任意长度整数的字符串表示形式转换为十进制?

c - 如何在 Obj-C 应用程序中访问和使用 dylib?

c - 在 C 中使用外部

Java:在单独的进程中运行 Callable

java - 通过Java将echo的输出重定向到文件

c++ - 通过套接字将数据作为字符串发送的好方法是什么?

javascript - 访问存储在 Javascript 数组中的对象

python - 在 Python 中将整数 append 到空 NumPy 数组

java - 为什么我收到错误 : "Exception in thread "main"java. lang.NullPointerException”

linux - 使用 BASH 在不同的盒子上启动多个进程