2

我现在有这段代码,并且得到了一个我无法理解的输出。

这是我的 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

任何帮助,将不胜感激。

4

1 回答 1

0

p = (SymTable_T)malloc(sizeof(SymTable_T));. 那是不正确的。它只分配一个指针大小的缓冲区,因为SymTable_T它是一个指针。C 中的最佳实践是不要强制转换 malloc。所以应该是:p = malloc(sizeof *p);或者p = malloc(struct SymTable); ——kaylum

于 2017-06-22T08:46:34.590 回答