【发布时间】:2020-12-12 14:41:51
【问题描述】:
我看到了一些关于这类问题的问题,但到目前为止都没有帮助。
代码在控制台上运行良好,但调试器告诉我在main 上为指针*word 分配内存时发生了分段错误,就在包含switch 语句的while 之后。它说argv[optind] 指向NULL,我认为它是因为在调试期间它没有归因于它的值。
所以,如果我觉得我知道会发生什么,我为什么要问这个问题,你可能会问。这是因为我的一个课程使用了在线代码测试器,并且我的代码在那里出现了段错误,所以,我对此不太熟悉,不确定是不是我的错。
代码按照我发布的方式运行,你可以编译运行,它在文本文件中搜索一个单词;示例:./my_grep "word" "file"
谢谢。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#define LINE 1000
static char* word=NULL;
int hasMultiWords=0, iflag=0, vflag=0, lflag=0, cflag=0;
void lowCase(char* s){
//Nesta funcao recebe um apontador para o inicio de uma string, assim funciona com arrays in *char;
for(int j=0; j<strlen(s); j++){
*(s+j) = tolower(*(s+j));
}
}
void readFile(FILE* in, FILE* out, int argc, char *file_name){
char line[LINE];
memset(line, 0, sizeof(char)*1000);
int n_linhas=0;
while( fgets(line, LINE, in) ){
n_linhas++;
if( cflag==1 && strstr(line, word) !=NULL ){
printf("%d\n", n_linhas);
continue;
}
if(iflag == 1){
lowCase(word);
char *ptr;
ptr = &line[0];
lowCase(ptr);
}
if( strstr(line, word) != NULL && vflag == 0){
if(lflag == 1){
fprintf(stdout, "%s", file_name);
break;
}
fprintf(stdout, "%s", line);
}
if( strstr(line, word) != NULL && vflag == 1 ){
if(lflag == 1){
fprintf(stdout, "%s", file_name);
break;
}
fprintf(stdout, "%s", line);
}
}
}
int main(int argc, char* argv[]){
FILE* read;
char* file_name;
int opt, weirdArgs=0;
while( (opt=getopt(argc, argv, "ivlc")) != -1){
switch(opt){
case 'i':
iflag=1;
break;
case'v':
vflag=1;
break;
case 'l':
lflag=1;
break;
case 'c':
cflag=1;
break;
default:
break;
}
}
if(optind > 0){
word = malloc(sizeof(char)*strlen(argv[optind]));
word = argv[optind];
}
optind++;
for(; optind<argc; optind++){
weirdArgs++;
file_name = realloc(file_name, sizeof(char)*strlen(argv[optind]));
file_name = argv[optind];
if( strcmp(file_name, "-") == 0){
readFile(stdin, stdout, argc, "stdin");
}else{
if( access(file_name, F_OK) != 0 ){
fprintf(stderr, "%s : No such file.\n", file_name);
continue;
}
read = fopen(file_name, "r");
readFile(read, stdout, argc, file_name);
fclose(read);
}
free(file_name);
}
if(weirdArgs == 0) readFile(stdin, stdout, argc, "stdin");
return 0;
}
编辑:所以,它是固定的,我添加了一个 if 语句来检查是否有参数,如果没有,则使程序打印在 stderr 中,因此它不会发现未分配的 optind。谢谢!
if(argc == 1){
fprintf(stderr, "No arguments found.\n");
exit(2);
}
【问题讨论】:
-
word = argv[optind];覆盖 word 并丢失您刚刚从 malloc 获得的内存。 -
在那之前我被卡住了。我对文档的阅读是 getopt() 返回一个 tuple 。 . .不是整数。据我所知,这也不应该在控制台上工作。我错过了什么?
-
如果你不传递任何参数,或者你只传递参数开关,你的程序将有未定义的行为,因为行
if (optind > 0)确实not认为optind也可以等于或大于argc。所以argv[optind]是未定义的。如前所述,malloc/realloc调用只是泄漏内存。即使你使用strcpy(你应该这样做),你也没有分配足够的字节来包含字符串终止符,所以你又会遇到问题。 -
@FrankMerrow:getopt 返回单个字符,在 C 中是一个 int。返回值要么是被识别的单字符选项,要么是一些指示错误的特殊字符,或者 -1 指示已到达参数列表的末尾。 C 没有元组。
-
另外,
malloc(sizeof(char)*strlen(argv[optind]));不会为终止的空字节分配空间。
标签: c pointers debugging segmentation-fault argv