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