C帮助解释calloc segfault
我的代码中有以下行:C帮助解释calloc segfault,c,segmentation-fault,malloc,calloc,C,Segmentation Fault,Malloc,Calloc,我的代码中有以下行: DocumentNode *docNode = NULL; initDocNode(docNode, docID, wordFreq); 下面是initDocNode函数 void initDocNode(DocumentNode *docNode, int docID, int wordFreq) { docNode = calloc(1, sizeof(DocumentNode)); if (!docNode) fprintf(stde
DocumentNode *docNode = NULL;
initDocNode(docNode, docID, wordFreq);
下面是initDocNode函数
void initDocNode(DocumentNode *docNode, int docID, int wordFreq) {
docNode = calloc(1, sizeof(DocumentNode));
if (!docNode)
fprintf(stderr, ....);
docNode->docID = docID;
docNode->wordFrequency = wordFreq;
}
我有一个while循环来创建docNodes,但在某一点上,我得到了一个segfault,它包含以下回溯。看起来这是calloc内部发生的事情。如果您能帮助理解这一点,我们将不胜感激
_int_malloc (av=av@entry=0x396fbb8760 <main_arena>, bytes=bytes@entry=16)
at malloc.c:3718
3718 set_head(remainder, remainder_size | PREV_INUSE);
(gdb) backtrace
_int_malloc (av=av@entry=0x396fbb8760 <main_arena>, bytes=bytes@entry=16)
at malloc.c:3718
0x000000396f88098a in __libc_calloc (n=<optimized out>, elem_size=<optimized out>)
at malloc.c:3187
0x0000000000402270 in initDocNode (docnode=0x0, docID=680, wordFreq=1)
at ../util/indexerUtils.c:59
0x000000000040147b in ReconstructIndex (hashtable=0x7fffc8c561f8,
wordToAdd=0x1c3eab0 "mode", docID=680, wordFreq=1) at src/query_engine.c:337
0x0000000000401209 in ReadFile (file=0x7fffc8c5932a "cs_lvl3.dat")
at src/query_engine.c:267
0x0000000000400eff in main (argc=2, argv=0x7fffc8c58998) at src/query_engine.c:147
}
这是重建索引()
}尝试在函数体中使用**docNode而不是*docNode,因为更改不会反映在函数体之外。它在本地创建一个节点。
要将function pass参数作为&docNode调用。可以发布while循环的代码吗。你可能进入了一个无限循环并且内存不足。我将在一秒钟内添加while循环。不过,我不认为我有一个无限循环。我添加了一个print语句来查看我的进度,我注意到在为特定单词的678个doc调用initDocNode后,我得到了segfault作为旁注,您的
initDocNode
函数将对调用者没有影响。指针是按值传递的,因此docNode=
赋值只影响参数,而不影响调用者中的变量。@安德鲁:错误消息是什么意思?是:0_int_malloc(av)=av@entry=0x396fbb8760,字节=bytes@entry=16)在malloc.c:3718 3718集头(剩余物,剩余物尺寸,先前使用)<代码>字符c代码>应该是intc代码>。使用fseek
可能不可靠,请尝试重做逻辑以避免fseek。尝试在valgrind
下运行以查找溢出。您的意思是将函数声明为void initDocNode(DocumentNode**docNode,int docID,int wordFreq)
并使用initDocNode调用它(&docNode,docID,wordFreq)代码>对吗?是的,通过这样做,更改也会反映在调用点上。
HashTable *ReadFile(char *file){
FILE *fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "Error: Couldn't open file %s for reloading.\n", file);
return NULL;
}
HashTable *hashtable = calloc(1, sizeof(HashTable));
if (!hashtable) {
fprintf(stderr, "Error: Couldn't allocate memory for hashtable.\n");
return NULL;
}
char c;
bool done = false;
while (1){
int wordLength = 0;
//keep reading until you find a space
//this is to determine the length of the word
while ((c = fgetc(fp)) != ' '){
if (c == EOF){
// but if c is EOF, then we're done reading the file
done = true;
// break out of the loop counting word lenght
break;
}
wordLength++;
}
if (done){
// break out of loop reading file
break;
}
// now allocate memory for the word and null character
char *currWord = calloc(wordLength + 1, sizeof(char));
if (!currWord){
fprintf(stderr, "Failed to allocate memory to store %s\n", currWord);
continue;
}
//now reverse the pointer to the beginning of the word
fseek(fp, -(wordLength + 1), SEEK_CUR);
int numFiles;
// now read the word. If it's unsuccessful, then there's no more lines. exit
fscanf(fp, "%s %d", currWord, &numFiles);
printf("Processing %s\n", currWord);
int i = 0;
while (numFiles--) {
int docID;
int wordCount;
if (!fscanf(fp, " %d %d", &docID, &wordCount)) {
fprintf(stderr, "Error: Couldn't process document for word, %s.\n", currWord);
free(currWord);
continue;
}
if (!ReconstructIndex(&hashtable, currWord, docID, wordCount)) {
fprintf(stderr, "Error: Couldn't reconstruct index for word, %s\n", currWord);
free(currWord);
continue;
}
printf("%s: just processed %d document\n", currWord, i);
i++;
}
}
fclose(fp);
return hashtable;
int ReconstructIndex(HashTable **hashtable, char* wordToAdd, int docID, int wordFreq) {
//get the hash index
int hashIndex = JenkinsHash(wordToAdd, MAX_HASH_SLOT);
// if hash index is not taken
if ((*hashtable)->table[hashIndex] == NULL) {
// make document node
DocumentNode *newDocNode = NULL;
// newDocNode = initDocNode(newDocNode, docID, wordFreq);
initDocNode(&newDocNode, docID, wordFreq);
if (!newDocNode) {
fprintf(stderr, "Failed to make DocumentNode for %s.\n", wordToAdd);
return 0;
}
// make word node with this document node
WordNode *newWordNode = NULL;
newWordNode = initWordNode(newWordNode, wordToAdd, newDocNode);
if (!newWordNode) {
fprintf(stderr, "Failed to make WordNode for %s.\n", wordToAdd);
free(newDocNode);
return 0;
}
// make hash table node with this word node
HashTableNode *newHTNode = NULL;
newHTNode = initHashTNode(newHTNode, (void*)newWordNode, NULL);
if (!newHTNode) {
fprintf(stderr, "Failed to make HashTableNode for %s.\n", wordToAdd);
free(newDocNode);
free(newWordNode->word);
free(newWordNode);
return 0;
}
// put hashtablenode into table at the hash index
(*hashtable)->table[hashIndex] = newHTNode;
return 1;
}
// if hash index is taken
else {
// find word
HashTableNode *currHTNode = (*hashtable)->table[hashIndex];
int inHashTable = 0;
while (currHTNode) {
WordNode * currWordNode = (WordNode *)(currHTNode->hashKey);
if (strcmp(wordToAdd, currWordNode->word) == 0){
inHashTable = 1;
break;
}
currHTNode = currHTNode->next;
}
// if word was found
if (inHashTable) {
WordNode *currWordNode = (WordNode *)(currHTNode->hashKey);
// add document to this word's listing in hash index
// make new document node
DocumentNode *newDocNode = NULL;
// newDocNode = initDocNode(newDocNode, docID, wordFreq);
initDocNode(&newDocNode, docID, wordFreq);
if (!newDocNode) {
fprintf(stderr, "Failed to make DocumentNode for %s.\n", wordToAdd);
return 0;
}
// append this new doc node to back of other document nodes
DocumentNode *lastDocNode = currWordNode->doc;
while (lastDocNode->next) {
lastDocNode = lastDocNode->next;
}
lastDocNode->next = newDocNode;
// free(wordToAdd); // causes seg fault
return 1;
}
// if word was not found
else {
// add word node to hashtable at this index
// make new document node
DocumentNode *newDocNode = NULL;
// newDocNode = initDocNode(newDocNode, docID, wordFreq);
initDocNode(&newDocNode, docID, wordFreq);
if (!newDocNode) {
fprintf(stderr, "Failed to make DocumentNode for %s.\n", wordToAdd);
return 0;
}
// make word node with this document node
WordNode *newWordNode = NULL;
newWordNode = initWordNode(newWordNode, wordToAdd, newDocNode);
if (!newWordNode) {
fprintf(stderr, "Failed to make WordNode for %s.\n", wordToAdd);
free(newDocNode);
return 0;
}
// make hash table node with this word node
HashTableNode *newHTNode = NULL;
newHTNode = initHashTNode(newHTNode, (void*)newWordNode, NULL);
if (!newHTNode) {
fprintf(stderr, "Failed to make HashTableNode for %s.\n", wordToAdd);
free(newDocNode);
free(newWordNode->word);
free(newWordNode);
return 0;
}
// append this new hashtable node to end of other hashtable nodes at hash index
HashTableNode *lastHTNode = (*hashtable)->table[hashIndex];
while (lastHTNode->next) {
lastHTNode = lastHTNode->next;
}
lastHTNode->next = newHTNode;
return 1;
}
}