在 c 中使用 realloc 4 次后访问结构成员的段错误
Segfault accessing struct member after using realloc 4 times in c
每当 nTable->size = 4 时,我都会遇到段错误,我终究无法弄清楚为什么。我在发生段错误的代码中添加了注释。目的是读入一个文本文件并创建一个 trie(我认为这是一个 trie?)读入的单词,如果它们共享相同的前几个字母,则重新使用前一个单词的字母。这段代码只用了1个字(abcde)来演示
#include <stdbool.h>//for bool
#include <stdlib.h> //for malloc
#include <string.h> //strlen, strchr
#include <ctype.h> //tolower
#include <stdio.h>
#define CHARACTERS 27
typedef struct node
{
struct node *nLetter[CHARACTERS];
bool end;
int size;
} node;
const char *cLetters = "abcdefghijklmnopqrstuvwxyz'";
node *nTable;
int main ()
{
char *cWord = "abcde";
nTable = malloc(sizeof(node));
if (nTable == NULL){
return false;
}
nTable->size = 1; //initialize table to size 1
nTable->end = false;//word not 0 letters
node *nPath = NULL; //create the path between each letter of the word
int iLen = 0;
iLen = strlen(cWord);
if(cWord[iLen - 1] == '\n') //strlen counts \n as a character, but not [=10=] (end of string). -1 if \n included
{
iLen--;
}
//store word in table
nPath = nTable; //reset path to beginning of table
for (int n = 0; n < iLen; n++)
{
char *p = strchr(cLetters, tolower(cWord[n]));
//Check Path
if (nPath->nLetter[p - cLetters] == NULL) //If path exists, move along path (in else below)
{ //if no path yet, create below.
nTable = realloc(nTable, ++nTable->size * sizeof(node)); //increase size of nTable by 1 node
if (nTable == NULL)
{
return false; //failed to increase size of nTable
}
//Connect Path
nPath->nLetter[p - cLetters] = nTable + (nTable->size - 1) * sizeof(node); //create path from previous letter to next
nPath = nPath->nLetter[p - cLetters]; //update nPath pointee to newest letter
if (n + 1 == iLen) //last letter of word
{
nPath->end = true;
}
else //not last letter of word
{
nPath->end = false; //SEGFAULT HERE when nTable->size is 4 or more
}
} //end if new path (if)
else //path exists, move along path
{
nPath = nPath->nLetter[p - cLetters];
}
}
return true;
}
我认为有问题的是这一行:
nPath->nLetter[p - cLetters] = nTable + (nTable->size - 1) * sizeof(node); //create path from previous letter to next
当你做指针运算时,你不应该乘以类型的大小。
相反,该行应该是:
nPath->nLetter[p - cLetters] = nTable + nTable->size - 1;
每当 nTable->size = 4 时,我都会遇到段错误,我终究无法弄清楚为什么。我在发生段错误的代码中添加了注释。目的是读入一个文本文件并创建一个 trie(我认为这是一个 trie?)读入的单词,如果它们共享相同的前几个字母,则重新使用前一个单词的字母。这段代码只用了1个字(abcde)来演示
#include <stdbool.h>//for bool
#include <stdlib.h> //for malloc
#include <string.h> //strlen, strchr
#include <ctype.h> //tolower
#include <stdio.h>
#define CHARACTERS 27
typedef struct node
{
struct node *nLetter[CHARACTERS];
bool end;
int size;
} node;
const char *cLetters = "abcdefghijklmnopqrstuvwxyz'";
node *nTable;
int main ()
{
char *cWord = "abcde";
nTable = malloc(sizeof(node));
if (nTable == NULL){
return false;
}
nTable->size = 1; //initialize table to size 1
nTable->end = false;//word not 0 letters
node *nPath = NULL; //create the path between each letter of the word
int iLen = 0;
iLen = strlen(cWord);
if(cWord[iLen - 1] == '\n') //strlen counts \n as a character, but not [=10=] (end of string). -1 if \n included
{
iLen--;
}
//store word in table
nPath = nTable; //reset path to beginning of table
for (int n = 0; n < iLen; n++)
{
char *p = strchr(cLetters, tolower(cWord[n]));
//Check Path
if (nPath->nLetter[p - cLetters] == NULL) //If path exists, move along path (in else below)
{ //if no path yet, create below.
nTable = realloc(nTable, ++nTable->size * sizeof(node)); //increase size of nTable by 1 node
if (nTable == NULL)
{
return false; //failed to increase size of nTable
}
//Connect Path
nPath->nLetter[p - cLetters] = nTable + (nTable->size - 1) * sizeof(node); //create path from previous letter to next
nPath = nPath->nLetter[p - cLetters]; //update nPath pointee to newest letter
if (n + 1 == iLen) //last letter of word
{
nPath->end = true;
}
else //not last letter of word
{
nPath->end = false; //SEGFAULT HERE when nTable->size is 4 or more
}
} //end if new path (if)
else //path exists, move along path
{
nPath = nPath->nLetter[p - cLetters];
}
}
return true;
}
我认为有问题的是这一行:
nPath->nLetter[p - cLetters] = nTable + (nTable->size - 1) * sizeof(node); //create path from previous letter to next
当你做指针运算时,你不应该乘以类型的大小。 相反,该行应该是:
nPath->nLetter[p - cLetters] = nTable + nTable->size - 1;