1

该程序可以编译,但是当运行时输出 find() 方法中的一些第一个打印语句,然后Segmentation fault:11在 for 循环命中时发出。

所以我尝试使用 gdb 进行调试,但无法弄清楚问题所在。根据我从 gdb 收集的信息,由于 strstr() 方法之一发生了段错误。另外,我注意到程序在调用 find 方法中的 for 循环之前关闭。为什么这个程序可以编译但在运行时崩溃?

这是 gdb 的输出:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000001
0x00007fff8d6469c4 in strstr ()
(gdb) 

感谢您的所有帮助。我实际上是 C 的完整初学者,但我正在努力学习更多。

#include <stdio.h>
#include <string.h>


int acdc_or_metallica(char *s);
int surfing_or_TV(char *s);
int exo_mustard(char *s);
int arts_theater_or_dining(char *s);

void find(int(*match)(char*));


int NUM_STUFF = 7;
char *STUFF[] = {

"Butthead likes ACDC and TV",
"Beavis likes Metallica and TV",
"Cartman likes to eat",
"Spiderman likes theater and working-out",
"Silver Surfer likes surfing and space",
"GunSword likes mustard and exoskeletons"
"Meatwad likes TV"

};


int main() 
{

find(acdc_or_metallica);
find(surfing_or_TV);
find(exo_mustard);
find(arts_theater_or_dining);

return 0;

}

int acdc_or_metallica(char *s)
{
return strstr(s, "acdc") || strstr(s, "metallica");
}

int surfing_or_TV(char *s)
{
return strstr(s, "surfing") || strstr(s, "TV");
}

int exo_mustard(char *s)
{
return strstr(s, "exoskeleton") && strstr(s, "mustard");
}

int arts_theater_or_dining(char *s)
{
return strstr(s, "arts") || strstr(s, "theater") || strstr(s, "dining");
}

void find(int(*match)(char*))
{
int i;
puts("Search results:");
puts("error below this line...");

puts("-----------------------------------------------");
for (i = 0;i < NUM_STUFF; i++) {
     if (match(STUFF[i])) {
        printf("%s\n", STUFF[i]);       
    }
}
puts("-----------------------------------------------");
}
4

2 回答 2

4

您正在match使用NULL指针调用。

您声明NUM_STUFF为 7(在 C 中应该是 a #define NUM_STUFF 7),并且您的STUFF数组有 5 个字符串,因为缺少两个逗号

"Silver Surfer likes surfing and space", /* you forgot the comma */
"GunSword likes mustard and exoskeletons", /* you forgot the comma */

(因为您忘记了逗号,而下一个标记是一个字符串,所以两行都连接在一个字符串中)

我通过 -ing 您的代码在 Linux 上发现了该错误indent,然后将其编译为gcc -Wall -g u1.c -o u1并运行gdb u1以对其进行调试。

你应该声明

#define NUM_STUFF 7
char *STUFF[NUM_STUFF] = {

实际上,您应该添加NULL终止数组的约定。然后你会有:

char *STUFF[] = {
  "Butthead likes ACDC and TV",
  "Beavis likes Metallica and TV",
  "Cartman likes to eat",
  "Spiderman likes theater and working-out",
  "Silver Surfer likes surfing and space",
  "GunSword likes mustard and exoskeletons", 
  "Meatwad likes TV",
  NULL
};

带有终止符的编码NULL使添加新句子变得更加容易。在这种情况下无需定义或更改NUM_STUFF

那么你的主循环将是

for (i = 0; STUFF[i] != NULL; i++)

风格提示:我发现

void find(int(*match)(char*));

相当难读。我个人更喜欢声明typedef潜在指向函数的签名,即我更喜欢编码

typedef int matchfun_t (char*);
void find (matchfun_t*);
于 2013-05-14T00:13:56.633 回答
2
 char *STUFF[] = {

"Butthead likes ACDC and TV",
"Beavis likes Metallica and TV",
"Cartman likes to eat",
"Spiderman likes theater and working-out",
"Silver Surfer likes surfing and space",
"GunSword likes mustard and exoskeletons" //<---- , 
"Meatwad likes TV"

};

你忘记了“,”,因为数据不够

于 2013-05-14T00:21:56.177 回答