我想将参数字符串复制到程序中的数组中。所以我写了下面的代码:
#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++;
}
答案 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]);
进行分配和复制。