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 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]));
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++;
}
source to share
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.
source to share