如何在C中摆脱"呼叫与源相同的表达"警告?

drd*_*dot 5 c string arguments

我想将参数字符串复制到程序中的数组中.所以我写了下面的代码:

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

int main(int argc, char *argv[]){
    // go through each string in argv
    int i = 0;
    while(i < argc){
        printf("arg %d: %s\n", i, argv[i]);
        i++;
    }

    //let's make our own array of strings
    char *states[] = {"California", "Oregon", "Washington", "Texas"};
    int num_states = 4;
    i = 0;  //watch for this
    while(i < num_states) {
        printf("state %d: %s\n", i, states[i]);
        i++;
    }

    //copy argv into strings
    char **dst;
    dst = (char**)malloc(sizeof(char*)*argc);
    for(i = 0; i < argc; i++){
        dst[i] = (char*)malloc(sizeof(char)*sizeof(argv[i]));
    }

    i = 0;
    while(i < argc){
        strncpy(*dst+i, argv[i], sizeof(argv[i]));
        printf("*dst = %s\n", *dst+i);
        i++;
    }

    for(i = 0; i < argc; i++){
        free(dst[i]);
    }
    free(dst);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

代码工作正常.但是有一个汇编警告:

cc -Wall -g -o ex11 ex11.c
ex11.c: In function ‘main’:
ex11.c:31:34: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
   strncpy(*dst+i, argv[i], sizeof(argv[i]));
Run Code Online (Sandbox Code Playgroud)

我怎么能摆脱这个警告?

更新1:我将dst指针的分配更改为以下内容:

  for(i = 0; i < argc; i++){
    //dst[i] = (char*)malloc(sizeof(char)*sizeof(argv[i]));
    dst[i] = (char*)malloc(strlen(argv[i]+1));
  }
  // ignore malloc null return
  printf("test 1 = %d\n", sizeof(char)*sizeof(argv[i]));
  printf("test 2 = %d\n", strlen(argv[i]));
Run Code Online (Sandbox Code Playgroud)

我想知道测试1和测试2是否会产生相同的数字.但对于测试2,它抱怨分段错误.这是为什么?

更新2:根据评论摆脱malloc循环:

  //copy argv into strings
  char **dst;
  dst = (char**)malloc(sizeof(char*)*argc);

  i = 0;
  while(i < argc){
    dst[i] = strdup(argv[i]);   //array version: strdup
    printf("*dst = %s\n", *(dst+i));
    i++;
  }
Run Code Online (Sandbox Code Playgroud)

Ben*_*igt 8

编译器是正确的,并告诉你一个危险的bug.您正在使用指针的大小,而不是指向它的字符串的大小.(实际的警告是说你要指定基于源复制的长度,这样做strcpy就像strncpy.在这种情况下它是错误的,因为它没有注意到它是指针的大小而不是数组.)

你也有一个严重的错误,与之*dst+i相同dst[0] + i,不是dst[i].你有i独立分配的指针,最好全部使用它们.

你应该改用

dst[i] = (char*)malloc(strlen(argv[i]) + 1); // remember space for the NUL character
Run Code Online (Sandbox Code Playgroud)

strcpy(dst[i], argv[i]);
Run Code Online (Sandbox Code Playgroud)

或者更好,只是

dst[i] = strdup(argv[i]);
Run Code Online (Sandbox Code Playgroud)

它进行分配和复制.