我现在有这段代码,并且得到了一个我无法理解的输出。
这是我的 symTable 模块,它具有操作符号表所需的所有功能。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include "symTable.h"
#define HASH_MULTIPLIER 65599
#define SIZE 61
struct SymTable {
char *key;
void *value;
struct SymTable *next;
};
/*--------------------------------------------------------------------*/
/* Hash string str to a hash table bucket index in range [0, htsize] */
static unsigned int hash(const char *key, const int htsize)
{
int i;
unsigned int h = 0U;
for (i = 0; key[i] != '\0'; i++)
h = h * HASH_MULTIPLIER + (unsigned char) key[i];
return h % htsize;
}
SymTable_T symTable_create(void)
{
SymTable_T p;
p = calloc(SIZE, sizeof(SymTable_T));
p->key = (char*)calloc(1, sizeof(char));;
return p;
}
void symTable_destroy(SymTable_T symTable)
{
SymTable_T p, nextp;
int i;
assert(symTable != NULL);
for (i = 0; i < SIZE; i++) {
for (p = symTable; p != NULL; p = nextp) {
nextp = p->next;
assert(p->key != NULL);
p=NULL;
}
}
free(symTable);
return;
}
int symTable_size(SymTable_T symTable)
{
SymTable_T p, nextp;
int i=0;
assert(symTable != NULL);
for (p = symTable; p != NULL; p = nextp) {
nextp = p->next;
i++;
}
return i;
}
int symTable_insert(SymTable_T symTable, const char *key,
const void *value, size_t valuesize)
{
SymTable_T p, prevp = NULL;
int h;
assert(symTable != NULL);
if (key == NULL)
return 0; // insert failed: return 0
/* Get hash of key*/
h = hash(key, SIZE);
for (p = symTable; p != NULL; prevp = p, p = p->next) {
if (hash(p->key, SIZE) == h)
{
return 0;
}
}
p = (SymTable_T)malloc(sizeof(SymTable_T));
if (p == NULL)
return 0;
p->key =(char*) key;
p->value = (void*)calloc(1, valuesize);
memcpy(p->value, value, valuesize);
p->next = NULL;
if (symTable == NULL)
symTable = p;
else
prevp->next = p;
return 1;
}
int symTable_search(SymTable_T symTable, const char *key,
void *value, size_t valuesize)
{
SymTable_T p;
int i;
assert(symTable != NULL);
for (i = 0; i < SIZE; i++) {
for (p = symTable->next; p != NULL; p = p->next) {
if (strcmp(p->key, key) == 0)
{
//value = (void*)calloc(1, valuesize);
memcpy(value, p->value, valuesize);
// printf("%c"()
return 1;
}
}
}
return 0;
}
int symTable_delete(SymTable_T symTable, const char *key)
{
SymTable_T p, nextp;
int i;
assert(symTable != NULL);
for (i = 0; i < SIZE; i++) {
for (p = symTable->next; p != NULL; p = nextp) {
nextp = p->next;
assert(p->key != NULL);
if (strcmp(p->key, key) == 0)
{
p = NULL;
return 1;
}
}
}
return 0;
}
我有一个头文件和一个C客户端文件来运行程序。
主要客户文件是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symTable.h"
int main(int argc, char *argv[])
{
char *key[4] = { "Einstein", "Newton", "Bohr", "Curie" };
char cvalue, char_value[4] = { 'e', 'n', 'b', 'c' };
int ivalue, int_value[4] = { 10, 20, 30, 40 };
float fvalue, float_value[4] = { 1.11, 2.22, 3.33, 4.44 };
double darray[2], double_array[4][2] = { { 1.11, 2.22 },
{ 3.33, 4.44 }, { 5.55, 6.66 }, { 7.77, 8.88 } };
int i, rv;
SymTable_T charTable, intTable, floatTable, double_arrayTable;
/* Create and insert character values into symbol table. */
printf("\nCreating symbol table with character values\n");
printf("-------------------------------------------\n");
charTable = symTable_create();
if (charTable == NULL) {
fprintf(stderr, "Cannot create character table\n");
return 1;
}
for (i = 0; i < 4; i++) {
printf("Insert <%s, %c>\n", key[i], char_value[i]);
rv = symTable_insert(charTable, key[i], &char_value[i], sizeof(char));
if (!rv) {
fprintf(stderr, "Insert failed for %s\n", key[i]);
return 1;
}
}
/* Create and insert integer values into symbol table. */
printf("\nCreating symbol table with integer values\n");
printf("-----------------------------------------\n");
intTable = symTable_create();
if (intTable == NULL) {
fprintf(stderr, "Cannot create integer table\n");
return 1;
}
for (i = 0; i < 4; i++) {
printf("Insert <%s, %d>\n", key[i], int_value[i]);
rv = symTable_insert(intTable, key[i], &int_value[i], sizeof(int));
if (!rv) {
fprintf(stderr, "Insert failed for %s\n", key[i]);
return 1;
}
}
/* Create and insert float values into symbol table. */
printf("\nCreating symbol table with float values\n");
printf("---------------------------------------\n");
floatTable = symTable_create();
if (floatTable == NULL) {
fprintf(stderr, "Cannot create float table\n");
return 1;
}
for (i = 0; i < 4; i++) {
printf("Insert <%s, %g>\n", key[i], float_value[i]);
rv = symTable_insert(floatTable, key[i], &float_value[i], sizeof(float));
if (!rv) {
fprintf(stderr, "Insert failed for %s\n", key[i]);
return 1;
}
}
/* Create and insert an array two double values into symbol table. */
printf("\nCreating symbol table with arrays of two double values\n");
printf("------------------------------------------------------\n");
double_arrayTable = symTable_create();
if (double_arrayTable == NULL) {
fprintf(stderr, "Cannot create double array table\n");
return 1;
}
for (i = 0; i < 4; i++) {
printf("Insert <%s, [%g, %g]>\n", key[i], double_array[i][0], double_array[i][1]);
rv = symTable_insert(double_arrayTable, key[i], &double_array[i][0], 2*sizeof(double));
if (!rv) {
fprintf(stderr, "Insert failed for %s\n", key[i]);
return 1;
}
}
/* Search and print <key, value> pairs in character table, then delete */
printf("\nSearching symbol table with character values\n");
printf("--------------------------------------------\n");
for (i = 0; i < 4; i++) {
rv = symTable_search(charTable, key[i], &cvalue, sizeof(char));
if (rv) {
printf("%s found, value = %c: now deleting\n", key[i], cvalue);
if (!symTable_delete(charTable, key[i])) {
fprintf(stderr, "Delete failed for %s\n", key[i]);
return 1;
}
}
else {
fprintf(stderr, "Search failed for %s\n", key[i]);
return 1;
}
}
/* Search and print <key, value> pairs in integer table, then delete */
printf("\nSearching symbol table with integer values\n");
printf("------------------------------------------\n");
for (i = 0; i < 4; i++) {
rv = symTable_search(intTable, key[i], &ivalue, sizeof(int));
if (rv) {
printf("%s found, value = %d: now deleting\n", key[i], ivalue);
if (!symTable_delete(intTable, key[i])) {
fprintf(stderr, "Delete failed for %s\n", key[i]);
return 1;
}
}
else {
fprintf(stderr, "Search failed for %s\n", key[i]);
return 1;
}
}
/* Search and print <key, value> pairs in float table, then delete */
printf("\nSearching symbol table with float values\n");
printf("----------------------------------------\n");
for (i = 0; i < 4; i++) {
rv = symTable_search(floatTable, key[i], &fvalue, sizeof(float));
if (rv) {
printf("%s found, value = %g: now deleting\n", key[i], fvalue);
if (!symTable_delete(floatTable, key[i])) {
fprintf(stderr, "Delete failed for %s\n", key[i]);
return 1;
}
}
else {
fprintf(stderr, "Search failed for %s\n", key[i]);
return 1;
}
}
/* Search and print <key, value> pairs in double array table, then delete */
printf("\nSearching symbol table with arrays of two double values\n");
printf("-------------------------------------------------------\n");
for (i = 0; i < 4; i++) {
rv = symTable_search(double_arrayTable, key[i], &darray, 2*sizeof(double));
if (rv) {
printf("%s found, value = [%g, %g]: now deleting\n", key[i], darray[0], darray[1]);
if (!symTable_delete(double_arrayTable, key[i])) {
fprintf(stderr, "Delete failed for %s\n", key[i]);
return 1;
}
}
else {
fprintf(stderr, "Search failed for %s\n", key[i]);
return 1;
}
}
symTable_destroy(charTable);
symTable_destroy(intTable);
symTable_destroy(floatTable);
symTable_destroy(double_arrayTable);
return 0;
}
头文件还包括结构:
typedef struct SymTable *SymTable_T;
我目前的输出是这样的,正如你所看到的,这些值是完全错误的,我不确定为什么。我认为问题出在关于内存的插入函数中,但我不确定:
我的输出:
Creating symbol table with character values
-------------------------------------------
Insert <Einstein, e>
Insert <Newton, n>
Insert <Bohr, b>
Insert <Curie, c>
Creating symbol table with integer values
-----------------------------------------
Insert <Einstein, 10>
Insert <Newton, 20>
Insert <Bohr, 30>
Insert <Curie, 40>
Creating symbol table with float values
---------------------------------------
Insert <Einstein, 1.11>
Insert <Newton, 2.22>
Insert <Bohr, 3.33>
Insert <Curie, 4.44>
Creating symbol table with arrays of two double values
------------------------------------------------------
Insert <Einstein, [1.11, 2.22]>
Insert <Newton, [3.33, 4.44]>
Insert <Bohr, [5.55, 6.66]>
Insert <Curie, [7.77, 8.88]>
Searching symbol table with character values
--------------------------------------------
Einstein found, value = \300: now deleting
Newton found, value = \340: now deleting
Bohr found, value = : now deleting
Curie found, value = : now deleting
Searching symbol table with integer values
------------------------------------------
Einstein found, value = 1070416: now deleting
Newton found, value = 1070448: now deleting
Bohr found, value = 1071472: now deleting
Curie found, value = 0: now deleting
Searching symbol table with float values
----------------------------------------
Einstein found, value = 1.50248e-39: now deleting
Newton found, value = 1.50253e-39: now deleting
Bohr found, value = 1.50257e-39: now deleting
Curie found, value = 0: now deleting
Searching symbol table with arrays of two double values
-------------------------------------------------------
Einstein found, value = [2.12253e-314, 2.22]: now deleting
Newton found, value = [2.12253e-314, 4.44]: now deleting
Bohr found, value = [2.12253e-314, 6.66]: now deleting
Curie found, value = [0, 8.88]: now deleting
正确的输出应该是这样的:
Creating symbol table with character values
-------------------------------------------
Insert <Einstein, e>
Insert <Newton, n>
Insert <Bohr, b>
Insert <Curie, c>
Creating symbol table with integer values
-----------------------------------------
Insert <Einstein, 10>
Insert <Newton, 20>
Insert <Bohr, 30>
Insert <Curie, 40>
Creating symbol table with float values
---------------------------------------
Insert <Einstein, 1.11>
Insert <Newton, 2.22>
Insert <Bohr, 3.33>
Insert <Curie, 4.44>
Creating symbol table with arrays of two double values
------------------------------------------------------
Insert <Einstein, [1.11, 2.22]>
Insert <Newton, [3.33, 4.44]>
Insert <Bohr, [5.55, 6.66]>
Insert <Curie, [7.77, 8.88]>
Searching symbol table with character values
--------------------------------------------
Einstein found, value = e: now deleting
Newton found, value = n: now deleting
Bohr found, value = b: now deleting
Curie found, value = c: now deleting
Searching symbol table with integer values
------------------------------------------
Einstein found, value = 10: now deleting
Newton found, value = 20: now deleting
Bohr found, value = 30: now deleting
Curie found, value = 40: now deleting
Searching symbol table with float values
----------------------------------------
Einstein found, value = 1.11: now deleting
Newton found, value = 2.22: now deleting
Bohr found, value = 3.33: now deleting
Curie found, value = 4.44: now deleting
Searching symbol table with arrays of two double values
-------------------------------------------------------
Einstein found, value = [1.11, 2.22]: now deleting
Newton found, value = [3.33, 4.44]: now deleting
Bohr found, value = [5.55, 6.66]: now deleting
Curie found, value = [7.77, 8.88]: now deleting
任何帮助,将不胜感激。