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

时间:2014-12-21 05:54:10

标签: 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;
}

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

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]));

我怎样摆脱这个警告?

更新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]));

我想知道测试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++;
  }

1 个答案:

答案 0 :(得分:8)

编译器是对的,告诉你一个危险的bug。您正在使用指针的大小,而不是指向它的字符串的大小。 (实际的警告是说你要根据来源指定要复制的长度,使strcpy表现得像strncpy。在这种情况下,它是错误的,因为它没有注意到它是sizeof指针而不是数组。)

*dst+i也出现严重错误,与dst[0] + i相同,而非dst[i]。你有i个独立分配的指针,最好全部使用它们。

您应该使用

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

strcpy(dst[i], argv[i]);

或更好,只是

dst[i] = strdup(argv[i]);

进行分配和复制。