strncpy从** char到* char []没有复制最后一个元素

时间:2016-02-19 13:37:48

标签: c arrays strncpy

我正在尝试将argv的各个元素复制到第二个数组中。我正在使用strncpy来执行此操作。

这是一个复制问题的剥离版本。

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    printf("%d\n", argc);
    char *argvarray[argc];
    int arrlen;

    //int j;
    for(int j=0; j< argc; j++){
        arrlen = arrlen + strlen(argv[j]);
    }

    printf("size of argv: %d\n", arrlen); //see if size is right
    strncpy(*argvarray, *argv, arrlen);

    for(int j=0; j< argc; j++){
        printf("value of j: %d\n", j); //to see what's going on
        printf("%s\n", argv[j]); 
        printf("%s\n", argvarray[j]); //gets 1st element no problem
    }

    return 0;
}

如果我将1个arg传递给main,它会将argv的第一个元素复制到argvarray,但不复制第二个元素。如果我传递超过1个arg,则strncpy()上会出现段错误。

为什么会这样?什么是将char数组的所有元素(特别是在函数定义中声明的char数组)复制到其他char数组而不事先知道大小的最佳方法,如argv的情况?

4 个答案:

答案 0 :(得分:3)

arrlen = arrlen + strlen(argv[j]);

arrlen未初始化(未定义的行为)。

正如@ PeterA.Schneider指出的那样,argvarray的每个元素都需要空间,malloc之前使用strncpystrdup

答案 1 :(得分:1)

你对数组与指针感到困惑。

如果声明一个数组char tab[2][3],它将被连续存储在内存中:

[h][e][y][y][o][u] (a simple example).

但是在这里,你有指针,所以char (*tab)[2]是一个由两个指针组成的数组:

tab = [0x1234][0x5678]
0x1234 = "hey"
0x5678 = "you"

strncpy复制内存的连续部分。要复制argv,请复制每个指针(为每个char*调用malloc + strcpy一个是最简单的选项)

(另见@ AlterMann的答案,这也是正确的)

答案 2 :(得分:1)

  1. arrlen未初始化。您增加其值然后尝试将其用作strncpy的参数。程序行为将是未定义的。改为写int arrlen = 0;

  2. argvarray是指向char的指针的数组。您没有为每个元素分配任何内存。 *argvarray相当于argvarray[0]char*strncpy,不指向任何内容。因此,{{1}}的行为将是未定义的。

答案 3 :(得分:0)

除了变量arrlen未初始化

int arrlen;

结果是执行循环后的变量值

for(int j=0; j< argc; j++){
    arrlen = arrlen + strlen(argv[j]);
}

将不确定此次电话

strncpy(*argvarray, *argv, arrlen); 

没有意义,并且有不确定的行为。

我认为你的意思是以下

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    printf("%d\n", argc);
    char *argvarray[argc];

    for ( int i = 0; i < argc; i++ )
    {
        argvarray[i] = malloc( strlen( argv[i] ) + 1 ); 
        strcpy( argvarray[i], argv[i] );
    }

    for ( int i = 0; i < argc; i++ )
    {
        printf( "value of i: %d\n", i ); //to see what's going on
        printf( "%s\n", argv[i] ); 
        printf( "%s\n", argvarray[i] ); //gets 1st element no problem
    }

    for ( int i = 0; i < argc; i++ ) free( argvarray[i] );

    return 0;
}