[英]C bsearch causing segmentation fault
I have the function call userInteractive(*anangramInfo) which pass in the pointer of struct anangramInfo and this struct contains the pointer "anagramPointer" to a actual anagrams. 我有函数调用userInteractive(* anangramInfo),它传入struct anangramInfo的指针,这个struct包含指向实际anagrams的指针“anagramPointer”。 So, i get the stdin from the user.
所以,我从用户那里得到了stdin。 then use that as a key of bsearch to find the pointer thoese anagram has the same anangram.sorted.
然后使用它作为bsearch的键来找到指针thoese anagram具有相同的anangram.sorted。 then move the pointer to left until the key is not matching the anagram.sorted, then move back to the right printf the anagram.word until the anagram.sorted is not match.
然后将指针移动到左边,直到键与anagram.sorted不匹配,然后向右移动打印anagram.word,直到anagram.sorted不匹配。 But it causing me the segmentation problems
但它导致我的分割问题
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "anagrams.h"
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#define SIZE 80
//struct
struct anagram {
char word[SIZE];
char sorted[SIZE];
};
struct anagramInfo {
struct anagram *anagramPtr;
int numOfAnagrams;
};
/* qsort struct comparision function (product C-string field) */
int sortedMemberCompare( const void *ptr1, const void *ptr2 )
{
struct anagram *ia = (struct anagram *)ptr1;
struct anagram *ib = (struct anagram *)ptr2;
return strcmp(ia->sorted, ib->sorted);
/* strcmp functions works exactly as expected from
comparison function */
}
void userInteractive( struct anagramInfo *anagramInfoPtr ){
struct anagram a;
char data[SIZE];
char *pos;
printf("Enter a word to search for anagrams [^D to exit]:\n");
fgets(data, SIZE, stdin);
//get ripe of the '\n'
pos=strchr(data, '\n');
*pos = '\0';
strncpy(a.word,data,sizeof(data));
//lowercase word
int i;
for(i=0;data[i] != '\0';i++)
{
data[i]=(char)tolower(data[i]);
}
/* sort array using qsort functions */
qsort(data,strlen(data), 1, charCompare);
strncpy(a.sorted,data,sizeof(data));
//struct pointer to the elements
struct anagram *ptr= (struct anagram *)bsearch(a.sorted,anagramInfoPtr-> anagramPtr ->sorted,anagramInfoPtr-> numOfAnagrams,sizeof(struct anagram),sortedMemberCompare);
printf(ptr->word);
while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) {
ptr--;
}
while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) {
printf(ptr ->word);
printf(" ");
ptr++;
}
}
Your oversight is that bsearch
is not searching on a contiguous array ; 你的疏忽是
bsearch
没有在一个连续的数组上搜索 ; it is not even searching in the right place, since you are searching for sorted strings , but you ought to search for sorted members of anagrams : 它甚至没有在正确的位置搜索,因为您正在搜索已排序的字符串 ,但您应该搜索已排序的字谜成员 :
struct anagram *ptr = (struct anagram *)bsearch(&a,
anagramInfoPtr-> anagramPtr,
anagramInfoPtr-> numOfAnagrams,
sizeof(struct anagram),
sortedMemberCompare);
Then, when bsearch
fails and returns NULL
, you do not check that ptr
is NULL
and use it; 然后,当
bsearch
失败并返回NULL
,你不检查ptr
是否为NULL
并使用它; hence the segfault. 因此,段错误。 (You also do not check
NULL
at the Ctrl-D). (您也不要在Ctrl-D处检查
NULL
)。
This is a modified version - I added back the charCompare
function and whipped up a main()
with five fixed strings in order to make it work, after a fashion. 这是一个修改过的版本 - 我添加了一个
charCompare
函数并用一个时尚的方式将一个带有五个固定字符串的main()
掀起来使其工作。
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#define SIZE 80
//struct
struct anagram {
char word[SIZE];
char sorted[SIZE];
};
struct anagramInfo {
struct anagram *anagramPtr;
int numOfAnagrams;
};
/* qsort struct comparision function (product C-string field) */
int sortedMemberCompare( const void *ptr1, const void *ptr2 )
{
struct anagram *ia = (struct anagram *)ptr1;
struct anagram *ib = (struct anagram *)ptr2;
return strcmp(ia->sorted, ib->sorted);
/* strcmp functions works exactly as expected from
comparison function */
}
int charCompare(const void *a, const void *b)
{
const char *aa = a, *bb = b;
if (*aa < *bb)
return -1;
if (*aa == *bb)
return 0;
return 1;
}
void userInteractive( struct anagramInfo *anagramInfoPtr ){
struct anagram a;
char data[SIZE];
char *pos;
printf("Enter a word to search for anagrams [^D to exit]:\n");
fgets(data, SIZE, stdin);
//get ripe of the '\n'
pos=strchr(data, '\n'); // In Windows this might be a "\r" maybe?
if (NULL == pos)
exit(0);
*pos = '\0';
strncpy(a.word,data,sizeof(data));
//lowercase word
int i;
for(i=0;data[i] != '\0';i++)
{
data[i]=(char)tolower(data[i]);
}
/* sort array using qsort functions */
qsort(data, strlen(data), 1, charCompare);
strncpy(a.sorted,data,sizeof(data));
//struct pointer to the elements
struct anagram *ptr = (struct anagram *)bsearch(&a,
anagramInfoPtr-> anagramPtr,
anagramInfoPtr-> numOfAnagrams,
sizeof(struct anagram),
sortedMemberCompare);
// You must check that ptr is not NULL.
if (NULL == ptr)
{
printf("Not found\n");
return;
}
printf("Found: %s\n", ptr->word);
/* Here there is a subtle error. If you find the FIRST item of the list,
this code will position itself BEFORE THE BEGINNING of the list, and
run a strncmp() against who knows what. Other segfault lurking! */
while(ptr > anagramInfoPtr -> anagramPtr && strncmp(ptr ->sorted,a.sorted,strlen(a.sorted))==0) {
ptr--;
}
// while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) {
// ptr--;
//}
// Here too you should check you do not pass max number of anagrams,
// if you hit the last item of the lot.
while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) {
printf(ptr ->word);
printf(" ");
ptr++;
}
}
int main()
{
int i;
struct anagramInfo *root;
root = malloc(sizeof(struct anagramInfo));
root->numOfAnagrams = 5;
root->anagramPtr = malloc(root->numOfAnagrams * sizeof(struct anagram));
strcpy(root->anagramPtr[0].word, "oriental");
strcpy(root->anagramPtr[1].word, "teaching");
strcpy(root->anagramPtr[2].word, "senator");
strcpy(root->anagramPtr[3].word, "admirer");
strcpy(root->anagramPtr[4].word, "rescued");
for (i = 0; i < root->numOfAnagrams; i++)
{
int j;
for (j = 0; root->anagramPtr[i].word[j]; j++)
root->anagramPtr[i].word[j] = tolower(root->anagramPtr[i].word[j]);
strcpy(root->anagramPtr[i].sorted, root->anagramPtr[i].word);
qsort(root->anagramPtr[i].sorted, strlen(root->anagramPtr[i].sorted), 1, charCompare);
}
qsort(root-> anagramPtr, root-> numOfAnagrams, sizeof(struct anagram), sortedMemberCompare);
for (;;)
userInteractive(root);
}
$ gcc -W -Wall -o anagram anagram.c
$ ./anagram
Enter a word to search for anagrams [^D to exit]:
treason
Found: senator
Enter a word to search for anagrams [^D to exit]:
cheating
Found: teaching
Enter a word to search for anagrams [^D to exit]:
relation
Found: oriental
Enter a word to search for anagrams [^D to exit]:
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.