strcpy()在可变大小的字符串数组上生成分段错误
我正在学习“C”语言,我创建了一个程序,如下所示,它将命令行参数复制到另一个可变大小的数组(字符串),并从索引2开始打印该数组strcpy()在可变大小的字符串数组上生成分段错误,c,C,我正在学习“C”语言,我创建了一个程序,如下所示,它将命令行参数复制到另一个可变大小的数组(字符串),并从索引2开始打印该数组 #include <stdio.h> #include <string.h> void print_array(const char* arr[]) { for (int i = 0; arr[i]; i++) { printf("%s\n", arr[i]); } } void copy_array(char
#include <stdio.h>
#include <string.h>
void print_array(const char* arr[]) {
for (int i = 0; arr[i]; i++) {
printf("%s\n", arr[i]);
}
}
void copy_array(char* dest[], const char* src[]) {
for (int i = 0; src[i]; i++) {
strcpy(dest[i], src[i]);
}
}
int main(int argc, const char* argv[]) {
if (argc < 2)
return 1;
char args[argc][256];
copy_array(args, argv);
print_array(&args[2]);
return 0;
}
#包括
#包括
无效打印数组(常量字符*arr[]{
for(int i=0;arr[i];i++){
printf(“%s\n”,arr[i]);
}
}
无效复制_数组(char*dest[],const char*src[]{
for(int i=0;src[i];i++){
strcpy(dest[i],src[i]);
}
}
int main(int argc,const char*argv[]{
如果(argc<2)
返回1;
字符args[argc][256];
复制_数组(args,argv);
打印数组(&args[2]);
返回0;
}
问题是,当我通过“./a.out一二三四五”调用它时,它抛出了一个分段错误。使用gdc,我可以看到strcpy()实现了这一点。我只是在学习,找不到真正的原因。有人能指出我做错了什么吗?似乎复制数组循环在数组的实际长度之后执行
void copy_array(char* dest[], const char* src[]) {
for (int i = 0; src[i]; i++) {
strcpy(dest[i], src[i]);
}
}
应改为
void copy_array(char* dest[], const char* src[], int count) {
for (int i = 0; i < count; i++) {
strcpy(dest[i], src[i]);
}
}
void copy_数组(char*dest[],const char*src[],int count){
for(int i=0;i
此外,打印阵列应更改为:
void print_array(const char* arr[], int count) {
for (int i = 0; i < count; i++) {
printf("%s\n", arr[i]);
}
}
void print_数组(常量字符*arr[],整数计数){
for(int i=0;i您的问题是字符的数组与指向字符的指针数组不同。这似乎有些迂腐,但其基本结构却不同
事实上,编译器应该发出警告(如果不是,则应该提高警告级别)
更具体地说,如果a
是一个字符数组,那么a[i]
是一个相对于数组开头的地址,只能计算该地址,因为编译器知道每个子数组有多大(例如,在您的情况下,256
)
然而,如果a
是指向char
的指针数组,则不需要计算,a[i]
包含指针本身的值
通过在需要指针数组的位置传递数组,会导致编译器错误地计算地址(即未定义的行为),从而导致错误
如果您希望保持一致并在任何地方使用指针数组,您的代码可能更像:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_array(char* arr[]) {
for (int i = 0; arr[i]; i++) {
printf("%s\n", arr[i]);
}
}
void copy_array(char* dest[], char* src[]) {
int i;
for (i = 0; src[i]; i++) {
dest[i] = malloc(strlen(src[i]) + 1);
strcpy(dest[i], src[i]);
}
dest[i] = NULL;
}
int main(int argc, char* argv[]) {
if (argc < 2)
return 1;
char *args[argc + 1];
copy_array(args, argv);
print_array(&args[2]);
return 0;
}
#包括
#包括
#包括
无效打印数组(字符*arr[]{
for(int i=0;arr[i];i++){
printf(“%s\n”,arr[i]);
}
}
无效复制_数组(char*dest[],char*src[]{
int i;
对于(i=0;src[i];i++){
dest[i]=malloc(strlen(src[i])+1;
strcpy(dest[i],src[i]);
}
dest[i]=NULL;
}
int main(int argc,char*argv[]){
如果(argc<2)
返回1;
字符*args[argc+1];
复制_数组(args,argv);
打印数组(&args[2]);
返回0;
}
使用固定长度的缓冲区会导致难看的缓冲区溢出错误。为什么不strdup
?看起来像是家庭作业。Jaymin Suthar,您使用的编译器没有警告行copy_数组(args,argv)代码>?我在Ubuntu机器上使用gcc 8.2.0,很抱歉之前没有提及,编译器确实警告过我。您的参数错误,copy_数组应该采用char*或char dest[],char*[]与char**相同,对于strcpy不正确,“argv”是字符串数组,您需要传递其中一个,而不是全部。argv[argc]
将始终是NULL@FatalError,我无法理解你在我的回答中试图指的是什么谢谢你的解释,它奏效了。现在我也更了解数组和指针。