How do I get rid of the "call is the same expression as the original" warning in C?

I would like to copy strings of arguments to an array in a program. So I wrote the following code:

#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 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;
}

      

The code works fine. But there is a compilation warning:

cc -Wall -g -o ex11 ex11.c
ex11.c: In functionmain’:
ex11.c:31:34: warning: argument tosizeofinstrncpycall 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]));

      

How can I get rid of this warning?

Update 1: I changed the dst pointer allocation to the following:

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

      

I want to know if test 1 and test 2 will generate the same number. But for test 2, it complains about a segmentation fault. Why is this?

Update 2: Get rid of the malloc loop based on the comment:

  //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++;
  }

      

+3


source to share


1 answer


The compiler is right and will tell you about a dangerous error. You are using the size of the pointer, not the size of the string it points to. (The actual warning says that you are specifying the length to copy based on the source, making it strcpy

act like strncpy

. In this case, it is wrong, though, since he didn't notice that it was a pointer size, not an array.)

You also had a serious error with *dst+i

which is the same as dst[0] + i

, not dst[i]

. You have i

independently assigned pointers, it is best to use them.

Instead, you should use

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

      

and



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

      

or better yet, just

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

      

which does the selection and copies both.

+7


source







All Articles