我正在学习“ 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* 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;
}
问题是,当我通过'./a.out一二三四五'进行调用时,使用gdc引发了分段错误,我知道strcpy()会这样做。我只是学习它,无法真正找到原因。有人可以指出我做错了什么吗?
答案 0 :(得分:1)
似乎copy_array循环在数组的实际长度之后执行
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 print_array(const char* arr[], int count) {
for (int i = 0; i < count; i++) {
printf("%s\n", arr[i]);
}
}
答案 1 :(得分:1)
您的问题是char
的数组数组与char
的指针数组不同。看起来有些古怪,但是底层结构却不同。
实际上,您的编译器应发出警告(如果不是,则应提高警告级别)。
更具体地说,如果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;
}