gpt4 book ai didi

c - 解析代码中的段错误

转载 作者:太空宇宙 更新时间:2023-11-04 07:08:25 27 4
gpt4 key购买 nike

我有这段代码专门提取两个指定字符串之间的字符串 <title></title> .但是当我运行程序时,我得到 Segmentation Fault: 11有什么解决办法吗?

int main(){

struct stat st;
stat("test.txt", &st);
int size = st.st_size;
printf("%d\n", size);
FILE *f = fopen("test.txt", "rb");

char *bytes = (char*)malloc(size);
fread(bytes,size,1,f);
fclose(f);
parser(bytes);
return 0;
}

void parser(char *bytes){
struct stat st;
stat(bytes, &st);
int size = st.st_size;
char *output = (char*)malloc(size);
char *ptr = strstr(bytes, "<title>");
char *ptr2 = strstr(ptr, "</title>");
if(ptr2){
strncpy(output, ptr+7, (ptr2 - (ptr+7)));
puts(output);
free(output);
parser(ptr2);
}
free(bytes);
free(output);

}

最佳答案

这里有不少问题。

排名不分先后:

  • 你正在双重释放 output (在您找到字符串的情况下)。这很可能会引发段错误,尽管不一定是在第二次调用 free 时发生的。 .您还释放了 bytes即使它不是从 malloc 返回的地址(在递归调用解析中)。这也会导致问题,而且是糟糕的设计:函数通常不应释放作为参数传递给它们的字符串。

  • 在解析器中,您正在调用 stat在文件的内容上,而不是在文件名上。这通常会失败,并且size将毫无意义。这尤其令人震惊,因为您实际上并不需要这个尺寸。

  • 您可能不想使用 strncpy . strncpy除非在原件中发现 NUL,否则不会以空值终止副本。因此,您最终会得到一个未终止的副本,这可能会造成各种破坏。

    相反,只需使用 memcpy (这也不会以 null 终止,但至少它不会让您误以为它可能)并自己添加 NUL。

  • 您最初从文件中读取的字符串不是以 NUL 结尾的。所以strstr将继续读取超出字符串末尾的部分。

  • parser是递归的而不是尾递归的。它可以很容易地编写为尾递归,并且您的 C 编译器可能能够在这种情况下应用 TCO,但正如所写的那样,它有可能建立一个大型调用堆栈。

  • parser不验证第一个 strstr在调用 strstr 之前找到一个字符串在结果上。所以当没有更多的<title>时要查找,您将调用 ptr2 = strstr(NULL, "</title>"); .那肯定会出现段错误。

下面是一些可能有用的代码:

/* Forward declare parser */
void parser(char *bytes);

int main(){
struct stat st;
stat("test.txt", &st);
/* CHECK RETURN VALUE */
int size = st.st_size;
printf("%d\n", size);
FILE *f = fopen("test.txt", "rb");
/* CHANGE: need space for the NUL */
char *bytes = malloc(size + 1);
size_t nread = fread(bytes,size,1,f);
if (nread != size) { /* HANDLE ERROR */ }
/* CHANGE: NUL terminate string */
bytes[nread] = 0;
fclose(f);
parser(bytes);
/* CHANGE: We allocated bytes, we free it */
free(bytes);
return 0;
}

void parser(char *bytes){
char *ptr = strstr(bytes, "<title>");
/* CHANGE: Make sure strstr found something */
if (ptr) {
/* Skip over the found string */
ptr += 7:
char *ptr2 = strstr(ptr, "</title>");
if (ptr2) {
/* Don't allocate buffer until we need it */
/* Remember to leave space for the NUL */
char* output = malloc(ptr2 - ptr + 1);
memcpy(output, ptr, ptr2 - ptr);
/* null-terminate */
output[ptr2 - ptr] = 0;
puts(output);
free(output);
parser(ptr2);
}
}
}

那也不是最好的代码。但它显示了一些您可以考虑的事情。

关于c - 解析代码中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30317077/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com