代码之家  ›  专栏  ›  技术社区  ›  Ajinkya

使用void指针的通用副本

  •  0
  • Ajinkya  · 技术社区  · 11 年前

    我实现了一个通用的快速排序,现在我想从命令行接受数组。下面是一个函数,它应该将字符指针从数组argv复制到基。我有分段错误。当我传递两个整数的地址时,副本工作正常。

    #include<stdio.h>
    
    void copy(void *src, void *dest, int size)
    {
        char *s, *d;
        int i;
    
        s = src;
        d = dest;
    
        for(i = 0; i < size; i++)
            d[i] = s[i];
    }
    
    int main(int argc, char *argv[])
    {
        void *base;
        int i = 10;
        int j = 20;
    
        printf("%d, %d\n", i, j);
        copy(&i, &j, sizeof(int));
        printf("%d, %d\n", i, j);
    
        copy(argv, base, sizeof(char *));
    
        return 0;
    }
    

    输出

    10, 20
    10, 10
    Segmentation fault (core dumped)
    
    4 回复  |  直到 11 年前
        1
  •  2
  •   Ingo Leonhardt    11 年前

    argv 是一个指针数组。如果你只想复制指针,你可以这样做:

     base = calloc( argc, sizeof(char *) );
     copy( argv, base, argc * sizeof(char *) );
    

    现在您有了指针数组的副本 argv公司 ,但它仍然包含指向原始参数的指针 argv[i] . 如果要创建的副本 参数[i] 也是,不要使用 copy() 但是:

     char **base = calloc( argc, sizeof(char *) );
     int  i;
    
     for( i=0; i<argc; i++ )
         base[i] = strdup( argv[i] );
    

    但请记住: argv[0] 是程序的名称,我敢打赌你不希望它成为数组的一部分。为了避免这种情况:

     base = calloc( argc-1, sizeof(char *) );
     copy( argv+1, base, (argc-1) * sizeof(char *) );
    

     char **base = calloc( argc, sizeof(char *) );
     int  i;
    
     for( i=1; i<argc; i++ )
         base[i-1] = strdup( argv[i] );
    
        2
  •  1
  •   alk    11 年前

    你正试图复制 sizeof(char*) 字节到其中 base 正在指向。但您没有将任何内存分配给 基础 因此程序调用未定义的行为。

        3
  •  0
  •   aah134    11 年前
    void *base = malloc(strlen(argv[0])+1);
    

    然后

    copy(argv[0], base, strlen(argv[0])+1);
    

    最后

    free(base);
    

    sizeof(char*) 将返回单个指针的大小,而不是整个路径的大小

    编辑:

    void *base;
    int i;
    
    if (argc>0)
    {
       base = malloc(argc+1);// we have enough pointers for copying args (+1 to null terminat it)
    
       for(i=0; i < argc; i++)
       {
          base[i] = malloc(strlen(argv[i])+1);
          copy(argv[i], base[i], strlen(argv[i])+1);
       }
       base[i] = NULL;
    }
    

    base将是一个包含所有参数的双指针

    你可以这样做 memset(...) memcopy(...) 顺便说一句

        4
  •  -1
  •   John    11 年前

    Argv不是单指针,而是双指针,

    你应该这样做:

    base = calloc(1, sizeof(char *));
    copy(argv[1], base, sizeof(char *));
    

    如果你真的想复制完整的argv,你必须替换 sizeof(char*)和strlen(argv[0]),并且必须以argv[0]的长度分配基数。