C 分割错误,但无法解释如何,内存分配在我看来很好

C 分割错误,但无法解释如何,内存分配在我看来很好,c,pointers,segmentation-fault,C,Pointers,Segmentation Fault,我有一个节点,我定义它的全局指针变量如下: typedef struct node { char* word; struct node* next; } node; node* HashTable = NULL; node* HeadOfHashTable = NULL; void allocateMemory(int numOfElements, bool isRealloc, const char* word) { if(!isRealloc) {

我有一个节点,我定义它的全局指针变量如下:

typedef struct node
{
    char* word;
    struct node* next;
} node;

node* HashTable =  NULL;
node* HeadOfHashTable = NULL;
void allocateMemory(int numOfElements, bool isRealloc, const char* word)
{
    if(!isRealloc)
    {
        printf("Allocating %d blocks\n", numOfElements);
        HashTable = malloc(sizeof(node*) * numOfElements);
    } else {
        printf("Reallocating %d blocks for %s", numOfElements, word);
        HashTable = realloc(HashTable, sizeof(node*) * numOfElements);
    }

    if(HashTable == NULL)
    {
        printf("### Out Of Memory ###\n");
        exit(0);
    }
    HeadOfHashTable = HashTable;
}
现在,我分配内存如下:

typedef struct node
{
    char* word;
    struct node* next;
} node;

node* HashTable =  NULL;
node* HeadOfHashTable = NULL;
void allocateMemory(int numOfElements, bool isRealloc, const char* word)
{
    if(!isRealloc)
    {
        printf("Allocating %d blocks\n", numOfElements);
        HashTable = malloc(sizeof(node*) * numOfElements);
    } else {
        printf("Reallocating %d blocks for %s", numOfElements, word);
        HashTable = realloc(HashTable, sizeof(node*) * numOfElements);
    }

    if(HashTable == NULL)
    {
        printf("### Out Of Memory ###\n");
        exit(0);
    }
    HeadOfHashTable = HashTable;
}
现在,我在下面的方法中传递一个散列值和一个单词放入散列表。我已经评论了我的seg故障

void putInHashTable(char* ch, unsigned int hashValue)
{
    HashTable += hashValue;

    printf("Processing at address: %p and has value was %d\n", HashTable, hashValue);

    if(HashTable == NULL || HashTable == '\0' || HashTable == 0)
    {
        printf("Hash table is NULL");
    }

    if(HashTable->word == NULL)
    {
        HashTable->word = malloc(sizeof(char) * (LENGTH + 1));
        strcpy(HashTable->word, ch);
        printf("New word: %s\n", HashTable->word);
    } else {
        printf("### Collision detected ###\n"); // ***** BELOW LINE GIVES SEG FAULT ******
        printf("    Earlier value is %s, new value is %s and its pointer is %p\n", HashTable->word, ch, HashTable->next);
        putInLinkedList(ch);
    }

    HashTable = HeadOfHashTable;
}
以下是控制台日志:

Allocating 65336 blocks
Processing at address: 0xb7568c28 and has value was 388
New word: a
Processing at address: 0xb756b9a0 and has value was 1843
New word: aaa
Processing at address: 0xb7570c08 and has value was 4480
New word: aaas
Processing at address: 0xb75ae608 and has value was 36032
### Collision detected ###
Segmentation fault (core dumped)
我的怀疑:

  • 我分配了65336个内存块,并且我得到seg fault的点的散列值为36032,因此我确信指针变量
    HashTable
    具有有效的内存地址。那为什么是seg故障呢
  • 如果它不是一个有效地址,那么为什么它没有被捕获在这个If条件下
    If(HashTable==NULL | | HashTable=='\0'| | HashTable==0)
    。我甚至使用了calloc,如果条件未被捕获,我也会得到seg fault和更高版本
  • 我在这一行得到seg错误
    printf(“以前的值是%s,新值是%s,它的指针是%p\n”,HashTable->word,ch,HashTable->next)。这意味着在取消引用指针时出现了一些问题,那么为什么在此之前我没有得到seg fault,这意味着我应该只在这里得到seg fault-
    如果(HashTable->word==NULL)
    • 数星星

       FOO * foo_ptr = malloc (sizeof (FOO) * n_foos);
       //  ^                                ^             
       //  |                                |
       //  one star to the left of `=`      one star to the right of `=`
      
      经验法则:任务两边的星星数必须相同。为什么?

            sizeof(FOO)    sizeof(FOO)    sizeof(FOO)   
           _____________  _____________  ______________
          /             \/             \/              \
           _____________  _____________  ______________
          [_____FOO_____][_____FOO_____][______FOO_____]
          ^
          |
          FOO* foo_ptr; // a FOO* points to a FOO
                        // pointer arithmetic works by incrementing the address\
                        // by sizeof(FOO)
                        // and so on
      
      好代码的其他示例:

       FOO ** foo_ptr = malloc (sizeof (FOO*) * n_foos); // same number of stars
       FOO *** foo_ptr = malloc (sizeof (FOO**) * n_foos); // still same
      
      错误代码:

       FOO ** foo_ptr = malloc (sizeof (FOO) * n_foos); // numbers don't match
       FOO * foo_ptr = malloc (sizeof (FOO*) * n_foos); // numbers don't match
      
      你的线路

      HashTable = malloc(sizeof(node*) * numOfElements);
      
      (在替换了
      HashTable
      的类型(即
      节点*
      )之后,它完全落入了坏代码箱,因此请尝试修复它

      如果需要节点数组,请执行以下操作:

      HashTable = malloc(sizeof(node) * numOfElements);
      
      如果你想要一个庞然大物阵列到节点,你也可以拥有它。这并不是真正的建议,因为节省的空间很小,性能可能会大幅下降,代码也不那么优雅。但你可以拥有它:

      node** HashTable = malloc(sizeof(node*) * numOfElements); // count! the! stars!
      
      恭喜你!现在您有了一个未初始化的
      numOfElements
      指针数组。现在需要将它们初始化为某个值,通常为NULL:

      for (i = 0; i < numOfElements; ++i) HashTable[i] = NULL;
      
      在这里,请注意这些与主要问题相关的时刻:如何正确地检查NULL,如何检查
      malloc
      的返回值,以及如何使用数组索引而不是来回改变全局指针变量。(如果要使用指针算法,请在
      putInHashTable
      中使用一个本地指针变量)

      (当然,如果你不使用n_foos或calloc,你需要对星星数进行心理调整)。

      计算星星数

       FOO * foo_ptr = malloc (sizeof (FOO) * n_foos);
       //  ^                                ^             
       //  |                                |
       //  one star to the left of `=`      one star to the right of `=`
      
      经验法则:任务两边的星星数必须相同。为什么?

            sizeof(FOO)    sizeof(FOO)    sizeof(FOO)   
           _____________  _____________  ______________
          /             \/             \/              \
           _____________  _____________  ______________
          [_____FOO_____][_____FOO_____][______FOO_____]
          ^
          |
          FOO* foo_ptr; // a FOO* points to a FOO
                        // pointer arithmetic works by incrementing the address\
                        // by sizeof(FOO)
                        // and so on
      
      好代码的其他示例:

       FOO ** foo_ptr = malloc (sizeof (FOO*) * n_foos); // same number of stars
       FOO *** foo_ptr = malloc (sizeof (FOO**) * n_foos); // still same
      
      错误代码:

       FOO ** foo_ptr = malloc (sizeof (FOO) * n_foos); // numbers don't match
       FOO * foo_ptr = malloc (sizeof (FOO*) * n_foos); // numbers don't match
      
      你的线路

      HashTable = malloc(sizeof(node*) * numOfElements);
      
      (在替换了
      HashTable
      的类型(即
      节点*
      )之后,它完全落入了坏代码箱,因此请尝试修复它

      如果需要节点数组,请执行以下操作:

      HashTable = malloc(sizeof(node) * numOfElements);
      
      如果你想要一个庞然大物阵列到节点,你也可以拥有它。这并不是真正的建议,因为节省的空间很小,性能可能会大幅下降,代码也不那么优雅。但你可以拥有它:

      node** HashTable = malloc(sizeof(node*) * numOfElements); // count! the! stars!
      
      恭喜你!现在您有了一个未初始化的
      numOfElements
      指针数组。现在需要将它们初始化为某个值,通常为NULL:

      for (i = 0; i < numOfElements; ++i) HashTable[i] = NULL;
      
      在这里,请注意这些与主要问题相关的时刻:如何正确地检查NULL,如何检查
      malloc
      的返回值,以及如何使用数组索引而不是来回改变全局指针变量。(如果要使用指针算法,请在
      putInHashTable
      中使用一个本地指针变量)


      (当然,如果你不使用n|foos,或者使用calloc,你需要对星星数进行心理调整)。

      if(HashTable==NULL | | HashTable=='\0'| | HashTable==0)
      如果你不确定如何检查NULL,请询问stackoverflow。我们是来帮忙的
      sizeof(node*)
      -->
      sizeof(node)
      调试器将告诉您崩溃发生的位置。
      HashTable=malloc(sizeof(node*)*numOfElements)==>
      HashTable=malloc(sizeof*HashTable*numOfElements)@hagrawal实际上,调试器将告诉您的不仅仅是崩溃发生的位置。了解如何使用它,它将在将来为您节省大量时间。
      如果(HashTable==NULL | | HashTable=='\0'| | HashTable==0)
      如果您不确定如何检查NULL,请询问stackoverflow。我们是来帮忙的
      sizeof(node*)
      -->
      sizeof(node)
      调试器将告诉您崩溃发生的位置。
      HashTable=malloc(sizeof(node*)*numOfElements)==>
      HashTable=malloc(sizeof*HashTable*numOfElements)@hagrawal实际上,调试器将告诉您的不仅仅是崩溃发生的位置。学习如何使用它,它将在将来为您节省大量时间。谢谢。我从@BLUEPIXY评论中发现了这个问题。实际上,我想要的只是为指针变量分配空间,这样我就不会占用内存中的全部空间,只占用指针变量空间。因此,理想情况下,我应该在这行
      HashTable+=hashValue之后执行
      malloc(sizeof(node))
      。尽管RHS和LHS的星数不匹配,但仍然是有效的分配。请参阅更新。是的,也有例外,总结在最后一行。谢谢,伙计,我会查看你的更新,给我一些时间。谢谢