gpt4 book ai didi

c - DLL 中的堆错误

转载 作者:太空宇宙 更新时间:2023-11-04 04:02:21 26 4
gpt4 key购买 nike

我正在寻找一些 C dll 编程方面的帮助。当我从 dll 中调用 free 时,我在 Visual Studio 中收到一个错误。该程序在 IDE 中的 Debug模式下运行良好,但是当我尝试以“不调试启动”的方式执行它时,程序崩溃了。我通过调试读到,堆是共享的,这可能解释了为什么代码在 F5 而不是 Ctrl-F5 下运行良好。这是正确的吗??

我四处搜索,了解到通过 dll-exe 边界传递动态分配的内存是危险的,但是因为我在同一个 dll 中调用 malloc 和 free,所以这应该不是问题。我已经发布了下面的代码。任何帮助将不胜感激。请注意,此代码适用于我的 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] != '\0'; 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 %d\n", 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 value\n");
free(temp_ptr->key);
printf("Deleted the key\n");
//printf("About to delete the node itself\n");
//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*));

参见 Do I cast the result of malloc?

关于c - DLL 中的堆错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10244931/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com