【问题标题】:Passing an array of strings to a C function by reference - invalid pointer通过引用将字符串数组传递给 C 函数 - 无效指针
【发布时间】:2012-08-13 15:26:59
【问题描述】:

我在通过 C 中的引用将字符串数组传递给函数时遇到问题。

上下文:我正在尝试使用一些命令制作一个非常简单的外壳。当在命令中键入命令时,命令的每个参数都保存在字符串数组的槽中。用于解析命令的函数称为 lineParsing(我没有这个的源代码 - 我只有 .o 和 .h)

有问题的函数具有以下标题:

void lineParsing (char **, int, char **, char **, char **, int *);

void lineParsing (char **item, int nargs, char **inputRedir, char **outputRedir, char **errorRedir, int *background);

函数说明如下: 指定参数数组(第一个参数)是否包含重定向或后台执行。

输入: 1-参数数组 2个参数 引用: 3-一个字符串数组,用于放置输入重定向的文件名 4-一个字符串数组,用于放置输出重定向的文件名 5-一个字符串数组,用于放置错误重定向的文件名 6-如果使用&,则在后台保存1,如果不是0

我在一个临时主程序中调用这个函数如下:

int main (int argc, char *argv[]){
    char **parrayArgumentos=NULL;
    int i,numargs,background;

    char *inputRedir[4]={"","","",""};
    char *outputRedir[4]={"","","",""};
    char *errorRedir[4]={"","","",""};

    parrayArgumentos = lineInput (&numargs); //Asks for command via standard input.
    printf ("You have typed in: %d arguments \n",numargs); //displays number of arguments

    i=0;
    while(i<=numargs-1){
        printf ("%s \n",parrayArgumentos[i]);
        i++;
    }

lineParsing(parrayArgumentos,numargs,inputRedir,outputRedir,errorRedir,&background);
//This call is problematic

    printf ("The command you have introduced has:\n%c for input redirection\n%c for output Redirection\n%s For error Ridirection\n%d background\n",inputRedir[0],outputRedir[0],errorRedir[0],background); 

    freeLineInput(parrayArgumentos);

    return 0;

}

通过我制作的 makefile 编译,没有错误或警告:

mishell: mishell.o parser64.o
    gcc mishell.o parser64.o -o mishell

mishell.o: mishell.c

clean:
    rm -f mishell.o mishell

当我执行二进制文件时,在调用 lineParsing 时出现以下错误:

[xxxx@xxxx src]$ ./mishell 
ls -la > listoffiles
You have typed in: 4 arguments 
ls 
-la 
> 
listoffiles 
*** glibc detected *** ./mishell: free(): invalid pointer: 0x0000000000401078 ***
======= Backtrace: =========
/lib/libc.so.6(+0x784a6)[0x7f8a5f76b4a6]
./mishell[0x400d99]
./mishell[0x4007b6]
/lib/libc.so.6(__libc_start_main+0xf5)[0x7f8a5f714725]
./mishell[0x4005e9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:04 7865560                            /home/xxxxx/Desktop/xxxx/xxxx/xxxxx/src/mishell
00601000-00602000 rw-p 00001000 08:04 7865560                            /home/xxxxx/Desktop/xxxxx/xxxxx/xxxxx/src/mishell
00e25000-00e46000 rw-p 00000000 00:00 0                                  [heap]
7f8a5f4de000-7f8a5f4f3000 r-xp 00000000 08:03 1185891                    /usr/lib/libgcc_s.so.1
7f8a5f4f3000-7f8a5f6f2000 ---p 00015000 08:03 1185891                    /usr/lib/libgcc_s.so.1
7f8a5f6f2000-7f8a5f6f3000 rw-p 00014000 08:03 1185891                    /usr/lib/libgcc_s.so.1
7f8a5f6f3000-7f8a5f88e000 r-xp 00000000 08:03 2490393                    /lib/libc-2.16.so
7f8a5f88e000-7f8a5fa8d000 ---p 0019b000 08:03 2490393                    /lib/libc-2.16.so
7f8a5fa8d000-7f8a5fa91000 r--p 0019a000 08:03 2490393                    /lib/libc-2.16.so
7f8a5fa91000-7f8a5fa93000 rw-p 0019e000 08:03 2490393                    /lib/libc-2.16.so
7f8a5fa93000-7f8a5fa97000 rw-p 00000000 00:00 0 
7f8a5fa97000-7f8a5fab8000 r-xp 00000000 08:03 2490410                    /lib/ld-2.16.so
7f8a5fc8a000-7f8a5fc8d000 rw-p 00000000 00:00 0 
7f8a5fcb4000-7f8a5fcb8000 rw-p 00000000 00:00 0 
7f8a5fcb8000-7f8a5fcb9000 r--p 00021000 08:03 2490410                    /lib/ld-2.16.so
7f8a5fcb9000-7f8a5fcba000 rw-p 00022000 08:03 2490410                    /lib/ld-2.16.so
7f8a5fcba000-7f8a5fcbb000 rw-p 00000000 00:00 0 
7fff8533d000-7fff8535e000 rw-p 00000000 00:00 0                          [stack]
7fff853ff000-7fff85400000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

我在 ArchLinux 3.4.4-2-ARCH x86_64 下使用 gcc 4.7.1

有人知道为什么会这样吗?

非常感谢您提前提供的所有帮助

【问题讨论】:

  • 您没有发布lineParsinglineInputfreeLineInput 的来源。这可能与您的问题有关。
  • 恐怕我没有来源。我只有这些函数的目标文件和头文件。
  • 如果没有它,恐怕我无法提供太多帮助。要么你的库有问题,要么你使用它的方式有问题。很难说。有相关文档吗?
  • 我拥有的文档提供了以下信息: char **lineInput (int *num_args) 从标准输入中读取一系列参数。参数可以用空格或制表符分隔。参数保存在字符串数组中。输入:保存参数数量的变量(通过引用) 输出:指向参数数组的指针。 void freeLineInput (char **item) 释放 lineInput() 保留的内存。必须在对 lineInput() 进行新调用之前调用它,以避免内存泄漏。输入:通过调用 lineInput() 保留的参数数组

标签: c arrays string pointers reference


【解决方案1】:

可能的原因是试图释放inputRediroutputRedirerrorRedir 中的任何元素如果它们没有改变。由于它们被初始化为字符串文字(空字符串),因此将其传递给 free() 是非法的:

如果 ptr 是空指针,则不执行任何操作。否则,如果 参数与 calloc、malloc 或 realloc 函数先前返回的指针不匹配,或者如果空间已通过调用 free 或 realloc 被释放, 行为未定义。

一个推测性的解决方法是将这三个数组的元素初始化为 NULL 指针(将 NULL 指针传递给 free() 是安全的):

char *inputRedir[4]  = { NULL, NULL, NULL, NULL };
char *outputRedir[4] = { NULL }; /* Unspecifed initializers will */
char *errorRedir[4]  = { NULL }; /* be NULL by default.          */

请注意printf() 语句中的格式说明符不正确,因为inputRedir[0](和outputRedir[0])是char*,但提供的格式说明符是%c,它用于char 类型:使用%schar*

【讨论】:

    猜你喜欢
    • 2011-07-08
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 2014-12-21
    • 2019-10-30
    • 2010-09-29
    • 1970-01-01
    • 2015-06-03
    相关资源
    最近更新 更多