0

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

#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

4 回答 4

2

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

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

现在您有了指针数组的副本argv,但它仍然包含指向原始参数的指针argv[i]。如果您也想创建副本argv[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] );
于 2013-09-19T14:19:50.033 回答
1

您正在尝试将sizeof(char*)字节复制到base指向的位置。但是您没有分配任何内存,base因此程序会调用未定义的行为。

于 2013-09-19T14:09:47.010 回答
0
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(...)顺便说一句

于 2013-09-19T14:19:37.253 回答
-1

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

你应该这样做:

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

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

于 2013-09-19T14:09:39.680 回答