[英]Learning Pointers in C
在過去48個小時左右的時間里,我一直在努力嘗試在C中實現此哈希表功能。我的代碼相當長(我意識到這不是最有效的方法,其中有些是我與C一起玩以獲得更多對其工作方式的感覺等)。
我遇到的問題是主程序的最后一行在底部(打印MyEntry-> Name)。 我收到總線錯誤,不確定為什么。 我不認為我應該在主驅動程序中為此指針分配內存,但是我可能錯了。
抱歉,這段代碼的長度。 BTW SymEntry是'struct SymEntry {char *名稱,無效*屬性,struct SymEntry *下一個}
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include "SymTab.h"
struct SymTab * CreateSymTab(int Size)
{
struct SymTab *symtable;
if(!(symtable=malloc(sizeof(struct SymTab)))) return NULL;
if(!(symtable->Contents=calloc(Size, sizeof(struct SymEntry*)))) {
free(symtable);
return NULL;
}
symtable->Size=Size;
return symtable;
}
/* hash form hash value for string s, taken from 'The C Programming Language'*/
unsigned hash(struct SymTab *ATable, const char *s)
{
unsigned hashval, size;
size = ATable->Size;;
for (hashval = 0; *s != '\0'; s++)
hashval = *s + 31 * hashval;
return hashval % size;
}
bool EnterName(struct SymTab *ATable,
const char *Name,
struct SymEntry **AnEntry)
{
struct SymEntry *ptr;
unsigned hashvalue;
char *string;
struct SymEntry *previous;
string = malloc(strlen(Name)+1);
AnEntry=(struct SymEntry**)malloc(sizeof(struct SymEntry*));
strcpy(string, Name);
printf("string is: is %s\n",string);
hashvalue = hash(ATable, string);
printf("hv is %d\n",hashvalue);
ptr = ATable->Contents[hashvalue];
previous = NULL;
while(ptr)
{
printf("WHILE LOOP\n");
if(!(strcmp(ptr->Name,string)))
{
printf("if(!strcmp(ptr->Name,string))\n");
*AnEntry = ptr;
return true;
}
previous = ptr;
ptr=ptr->Next;
}
if(previous)
{
printf("IF (PREVIOUS)\n");
if(!(ptr=malloc(sizeof(struct SymEntry)))) return false;
if(!(ptr->Name=string))
{
printf("if(!(ptr->Name=string))\n");
free(ptr);
return false;
}
ptr->Name = string;
previous->Next = ptr;
printf("Previous->Next: %s\n", previous->Next->Name);
*AnEntry = ptr;
return false;
}
else
{
printf("ELSE (PREVIOUS)\n");
if(!(ptr=malloc(sizeof(struct SymEntry)))) return false;
if(!(ptr->Name=string))
{
printf("if(!(ptr->Name=string))\n");
free(ptr);
return false;
}
ptr->Name = string;
ATable->Contents[hashvalue] = ptr;
printf("here\n");
*AnEntry = ptr;
printf("there\n");
return false;
}
}
struct SymEntry * FindName(struct SymTab *ATable, const char *Name)
{
struct SymEntry *Entry;
unsigned hashvalue;
hashvalue = hash(ATable, Name);
Entry = ATable->Contents[hashvalue];
while(Entry)
{
if(strcmp(Name,Entry->Name)==0)
{
return Entry;
}
}
return NULL;
}
main(int argc, char **argv)
{
struct SymTab *mysymtab;
struct SymEntry *myEntry;
mysymtab = CreateSymTab(1);
const char *string1 = "HELLO";
printf("%d\n",6);
EnterName(mysymtab, string1, &myEntry);
printf("first: %s\n", mysymtab->Contents[0]->Name);
EnterName(mysymtab, string1, NULL);
EnterName(mysymtab, "WORLD", NULL);
printf("second: %s\n", mysymtab->Contents[0]->Name);
printf("second->Next: %s\n", mysymtab->Contents[0]->Next->Name);
EnterName(mysymtab, "!@#$%", &myEntry);
printf("third: %s\n", mysymtab->Contents[0]->Name);
printf("third->Next: %s\n", mysymtab->Contents[0]->Next->Name);
printf("third->Next->Next: %s\n", mysymtab->Contents[0]->Next->Next->Name);
printf("myEntry->Name: %s\n", myEntry->Name);
}
問題是EnterName中的這一行:
AnEntry=(struct SymEntry**)malloc(sizeof(struct SymEntry*));
您需要刪除它,因為您希望AnEntry指向調用方指定的參數。
由於AnEntry可能為NULL,因此您還需要更改以下每個實例:
*AnEntry = ptr;
至:
if (AnEntry)
*AnEntry = ptr;
發生的情況是,當函數啟動時,AnEntry指向調用者想要更改的指針。 當您更改AnEntry的值(即AnEntry = ...;
)時,您的代碼將不會修改調用者希望您更改的指針,而是會修改一些內部指針。 因此,當EnterName返回時,myEntry仍指向內存中的某個隨機位置。
在學習時,您的代碼中包含一些樣式WTF。 以這一部分為例。
if(!(ptr=malloc(sizeof(struct SymEntry)))) return false;
if(!(ptr->Name=string))
{
printf("if(!(ptr->Name=string))\n");
free(ptr);
return false;
}
ptr->Name = string;
這是不一致的。 您為上面的AnEntry強制返回了malloc的返回值,但沒有強制執行此malloc的返回。 兩者之一,但不要混合。 更好的是,以根本不需要“強制轉換”的方式編寫它。
您不應在if語句內分配值。 雖然在malloc情況下仍要做什么,但在字符串分配中混淆了意圖。 特別是因為它是多余的。 如果if的值為true,則立即釋放ptr。 當評估結果為假時,將再次執行完全相同的分配。 此外,在這種情況下,它會阻止明顯的優化。
這是重寫的相同代碼:
if (string == NULL)
{
printf("string == NULL\n");
return false;
}
ptr = malloc(sizeof *ptr);
if (ptr == NULL)
{
return false;
}
ptr->Name = string;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.