C语言 DLL 中的堆错误



我正在寻找一些C dll编程的帮助。我在Visual Studio中收到一个错误,当我从dll中调用free时发生错误。该程序在 IDE 中的调试模式下运行良好,但是当我尝试将其作为"不调试启动"执行时,程序崩溃了。我读到调试,堆是共享的,这可能解释了为什么代码在 F5 而不是 Ctrl-F5 上运行良好。这是对的吗??

我四处搜索,我了解到通过 dll-exe 边界传递动态分配的内存是危险的,但是当我调用 malloc 并从同一个 dll 中释放时,这应该不是问题。我已经发布了下面的代码。任何帮助将不胜感激。请注意,此代码适用于我的 Linux 盒子,我只是尝试将其移植到 Windows 以获得在 Windows 中编程的经验。谢谢

#ifndef HASHTABLE_H
#define HASHTABLE_H
// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the HASHTABLE_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// HASHTABLE_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef HASHTABLE_EXPORTS
#define HASHTABLE_API __declspec(dllexport)
#else
#define HASHTABLE_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
  * This is a naive implementation
  * of a hashtable
  */
typedef struct node {
    struct node *next;
    char *value;
    char *key;
} Node;
typedef struct hashtable {
    struct node **nodes;
    int num_elements;
    int size;
    int (*hash_function)(const char * const);
} Hashtable_str;
// Construction and destruction
HASHTABLE_API void tbl_construct(Hashtable_str **table);
HASHTABLE_API void tbl_destruct(Hashtable_str *table);
// Operations
HASHTABLE_API int tbl_insert (Hashtable_str *table, const char * const key, const char * const element); // return the key
HASHTABLE_API int tbl_remove(Hashtable_str *table, const char * const key);
HASHTABLE_API char * tbl_find(Hashtable_str *table, const char * const key); // return the element
HASHTABLE_API int size(Hashtable_str *table); // Return the size
// default hash function
int def_hash(const char * const key);
#ifdef __cplusplus
}
#endif
#endif

这是实现代码

// hashtable.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "hashtable.h"
#include <stdlib.h> // for memcpy
#include <stdio.h>
#include <string.h>
#define SIZE 100
int def_hash(const char * const key)
{
    // simply sum the ascii
    // values and take modulo
    // 100
    //int i;
    //int sum;
    //sum = 0;
    //for (i=0; key[i] != ''; i++)
    //    sum += key[i];
    //return sum % SIZE;
    return 0;
}
// construct a hashtable and return a pointer
HASHTABLE_API void tbl_construct(Hashtable_str **tbl)
{
    int i;
    Hashtable_str *tbl_ptr;
    *tbl = (Hashtable_str*) malloc (sizeof(Hashtable_str*));
    tbl_ptr = *tbl;
    tbl_ptr->nodes = (Node**) malloc (SIZE * sizeof(Node*));
    for (i=0; i < SIZE; i++) tbl_ptr->nodes[i] = NULL;
    tbl_ptr->hash_function = &def_hash;
    tbl_ptr->num_elements = 0;
    tbl_ptr->size = SIZE;
}
HASHTABLE_API void tbl_destruct(Hashtable_str *tbl)
{
    void free_tbl_node(Node*); // declare the release function
    int i;
    for (i=0; i < tbl->size; i++)
    {
        if (tbl->nodes[i] != NULL)
            free_tbl_node(tbl->nodes[i]);
    }
}
void free_tbl_node(Node *curr_node)
{
    if (curr_node->next != NULL)
        free_tbl_node(curr_node->next);
    free(curr_node->value);
    curr_node->value = NULL;
    free(curr_node->key);
    curr_node->key = NULL;
    //free(curr_node);
    //Node *temp = NULL;
    //Node *temp2 = NULL;
    //temp = temp2 = curr_node;
    //while (temp->next != NULL)
    //{
    //    temp2=temp->next;
    //    free(temp->key);
    //    free(temp->value);
    //    free(temp);
    //    temp=temp2;
    //}
}
// table operations
HASHTABLE_API int count(Hashtable_str *tbl) { return tbl->num_elements; }
HASHTABLE_API int size(Hashtable_str *tbl) { return tbl->size; }
HASHTABLE_API int tbl_insert(Hashtable_str *table, const char * const key, const char * const element)
{
    int hash;
    Node *temp_ptr = NULL;
    hash = table->hash_function(key);
    //    printf("Placing into column %dn", hash);
    if (table->nodes[hash] == NULL)
    {
        table->nodes[hash] = (Node*) malloc(sizeof(Node*));
        temp_ptr = table->nodes[hash];
        temp_ptr->next = NULL;
        temp_ptr->key = (char*) malloc (strlen(key) + 1 * sizeof(char));
        temp_ptr->value = (char*) malloc (strlen(element) + 1 * sizeof(char));
        strcpy_s(temp_ptr->key, strlen(key)+1, key);
        strcpy_s(temp_ptr->value, strlen(element)+1, element);
        table->num_elements += 1;
    }
    else
    {
        // Collision!!
        temp_ptr = table->nodes[hash];
        while (temp_ptr->next != NULL)
            temp_ptr = temp_ptr->next;
        temp_ptr->next = (Node*) malloc(sizeof(Node));
        temp_ptr->next->key = (char*) malloc (strlen(key)+1 * sizeof(char));
        temp_ptr->next->value = (char*) malloc (strlen(element)+1 * sizeof(char));
        temp_ptr->next->next = NULL;
        strcpy_s(temp_ptr->next->key, strlen(key)+1, key);
        strcpy_s(temp_ptr->next->value, strlen(element)+1, element);
        table->num_elements += 1;
    }
    // Return the hash value itself for hacking
    return hash;
}
HASHTABLE_API int tbl_remove(Hashtable_str *tbl, const char * const key)
{
    int hash;
    Node *temp_ptr = NULL;
    Node *chain = NULL;
    hash = tbl->hash_function(key);
    if (tbl->nodes[hash] == NULL)
        return 1;
    else
    {
        temp_ptr = tbl->nodes[hash];
        if (strcmp(key, temp_ptr->key) == 0)
        {
            // The next node is the node in question
            chain = temp_ptr->next;
            free(temp_ptr->value);
            printf("Deleted the valuen");
            free(temp_ptr->key);
            printf("Deleted the keyn");
            //printf("About to delete the node itselfn");
            //free(temp_ptr);
            tbl->nodes[hash] = chain;
            tbl->num_elements -= 1;
            return 0;
        }
        else
        {
            while (temp_ptr->next != NULL)
            {
                if (strcmp(key, temp_ptr->next->key) == 0)
                {
                    // The next node is the node in question
                    // So grab a pointer to the node after it
                    // and remove the next node
                    chain = temp_ptr->next->next;
                    free(temp_ptr->next->key);
                    free(temp_ptr->next->value);
                    //free(temp_ptr->next);
                    temp_ptr->next = chain;
                    tbl->num_elements -= 1;
                    return 0;
                }
                else
                    temp_ptr = temp_ptr->next;
            }
        }
        // Couldn't find the node, so declare not existent
        return 1;
    }
}
HASHTABLE_API char * tbl_find(Hashtable_str *tbl, const char * const key)
{
    // Compute the hash for the index
    int hash;
    Node *temp_ptr = NULL;
    hash = tbl->hash_function(key);
    if (tbl->nodes[hash] == NULL)
        return NULL;
    else
    {
        temp_ptr = tbl->nodes[hash];
        if (strcmp(key, temp_ptr->key) != 0)
        {
            while (temp_ptr->next != NULL)
            {
                temp_ptr = temp_ptr->next;
                if (strcmp(key, temp_ptr->key) == 0)
                    return temp_ptr->value;
            }
        }
        // Couldn't find the node, so declare not existent
        return NULL;
    }
}

这是我的主要

#include <hashtable.h>
#include <utils.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    int i=0;
    Hashtable_str *my_table = NULL;
    tbl_construct(&my_table);
    tbl_insert(my_table, "Daniel", "Student");
    tbl_insert(my_table, "Derek", "Lecturer");
    //tbl_insert(my_table, "Melvyn", "Lecturer");
    tbl_print(my_table);
    printf("nRemoving Daniel...n");
    tbl_remove(my_table, "Daniel");
    //tbl_print(my_table);
    tbl_destruct(my_table);
    my_table = NULL;
    scanf_s("%d", &i);
    return 0;
}
这是不正确的,

因为分配的是指针的大小,而不是Hashtable_str

*tbl = (Hashtable_str*) malloc (sizeof(Hashtable_str*));

它应该是:

*tbl = malloc(sizeof(Hashtable_str));

同样的问题:

table->nodes[hash] = (Node*) malloc(sizeof(Node*));

请参阅我是否投射 malloc 的结果?

相关内容

  • 没有找到相关文章

最新更新