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,因此我确信指针变量
具有有效的内存地址。那为什么是seg故障呢HashTable
- 如果它不是一个有效地址,那么为什么它没有被捕获在这个If条件下
。我甚至使用了calloc,如果条件未被捕获,我也会得到seg fault和更高版本If(HashTable==NULL | | HashTable=='\0'| | HashTable==0)
- 我在这一行得到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))
但是我的疑问是,我怎么知道我是否已经为这个指针地址执行了malloc呢?这实际上是一个哈希表,所以如果我已经对空间进行了malloc'ed,那么我就不想再进行malloc了,因为我会将我的旧值丢失在类似的哈希值上代码>。尽管RHS和LHS的星数不匹配,但仍然是有效的分配。请参阅更新。是的,也有例外,总结在最后一行。谢谢,伙计,我会查看你的更新,给我一些时间。谢谢