I would like to copy the argument strings into an array in the 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'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;
}
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 allocation of the dst pointer into 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 is complaining about segmentation fault. Why is that?
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++;
}
The compiler is right, and telling you about a dangerous bug. You're using the size of a pointer, not the size of the string it points to. (The actual warning is saying you are specifying the length to copy based on the source, making strcpy
act like strncpy
. In this case it is wrong, though, because it didn't notice it is sizeof a pointer and not an array.)
You also had a serious error with *dst+i
, which is the same as dst[0] + i
, not dst[i]
. You've got i
independently allocated pointers, best to use them all.
You should instead 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 allocation and copy both.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With