C语言 如果我将指针转换为NULL会发生什么?



这里有一段代码:

assert_ptr_equals(get_data(hm,key_three),NULL);
assert_true((int*)get_data(hm,key_three)==NULL);

get_data函数返回一个void指针。第一个断言为真,但第二个断言失败。知道为什么吗?

这是最小可复制代码

#include<stdlib.h>
#include<stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h> 
#include <unistd.h> 
#define ASSERTION_FAILURE_EXITCODE 47
#define assert_true(x) assert_that(x)
#define assert_ptr_equals(x, y) assert_ptr_equals_internal(__FILE__, __extension__ __FUNCTION__, __LINE__, #x, x, #y, y)
#define assert_that(x) assert_that_internal(__FILE__, __extension__ __FUNCTION__, __LINE__, #x, x)
void assert_ptr_equals_internal(const char *file_name, const char *function_name, int line_number, const char *xname, void *x, const char *yname, void *y) {
if (x != y) {
fprintf(stderr, "%s:%s:%d: Expected <%s>:%p to be equal to <%s>:%p.n", file_name, function_name, line_number, xname, x, yname, y);
exit(ASSERTION_FAILURE_EXITCODE);
}
}
void assert_that_internal(const char *file_name, const char *function_name, int line_number, const char *condition_name, int condition) {
if (!condition) {
fprintf(stderr, "%s:%s:%d: Expected '%s' to hold.n", file_name, function_name, line_number, condition_name);
exit(ASSERTION_FAILURE_EXITCODE);
}
}


typedef void * Data;
typedef Data (* ResolveCollisionCallback)(Data oldData, Data newData);
typedef void (* CallbackIterate)(char * key, Data data);
typedef void (* DestroyDataCallback)(Data data);
typedef struct {
Data * data;                //Data pointer to the data
char * key;                 //char pointer to the string key
} HashMapItem;
typedef struct hashmap {
HashMapItem ** items;       //items of the hashmaps
size_t size;                //size of the hashmaps
int count;                  //how many elements are in the hashmap
} HashMap;
unsigned int hash(const char * key){
//sum of the charaters
unsigned int sum = 0;

for(int i=0; key[i] != ''; i++){
sum += key[i];
}
return sum;
}
HashMap * create_hashmap(size_t key_space){
if(key_space == 0)
return NULL;

HashMap * hm = (HashMap *) malloc(sizeof(HashMap));                         //allocate memory to store hashmap
hm->items = (HashMapItem **) calloc(key_space, sizeof(HashMapItem**));      //allocate memory to store every item inside the map, null it
hm->size = key_space;                                                       //set sitze of hashmap
hm->count = 0;                                                              //empty at the begining

return hm;
}
void insert_data(HashMap* hm, const char * key, const Data data, const ResolveCollisionCallback resolve_collison){
if(key == NULL || hm == NULL || data == NULL){
return;
}

//index where to put data
unsigned int index = hash(key) % hm->size;

if((hm->items)[index] != NULL){

(hm->items)[index]->data = (Data *)malloc(sizeof(Data *));                          //allocate memory to store the address

if(resolve_collison!=NULL)
*(hm->items)[index]->data = resolve_collison((hm->items)[index]->data, data);   //copy address of data into the hashmap
else
*(hm->items)[index]->data = data;                                               //if there is no resolve collision and there is data stored
                      //store the data pointer as is
}
else {
(hm->items)[index] = (HashMapItem *)malloc(sizeof(HashMapItem *));
(hm->items)[index]->data = (Data *)malloc(sizeof(Data *));  
*(hm->items)[index]->data = data; 
}
//allocate new space for the string key and copy it there
(hm->items)[index]->key = strdup(key);
}   
Data get_data(HashMap* hm, char* key){
if(key == NULL && hm == NULL)
return NULL;

unsigned int index = hash(key) % hm->size;
if((hm->items)[index] == NULL){
return NULL;
}    
return *(hm->items)[index]->data;
}
void remove_data(HashMap* hm, char * key, DestroyDataCallback destroy_data){
if(hm == NULL || key == NULL)
return;
unsigned int index = hash(key) % hm->size;

if((hm->items)[index] == NULL)
return;

if(destroy_data != NULL){
destroy_data((Data) *(hm->items)[index]->data);
}

free((hm->items)[index]->data);
free((hm->items)[index]->key);
free((hm->items)[index]);
}

void test1() {
HashMap *hm = create_hashmap(30);

char *key ="jsart", *key_two = ":@-)", *key_three = "stonks";
int x = 69, y = 420;
void *placeholder = &x, *placeholder_two = &y;

insert_data(hm, key_three, placeholder, NULL);
assert_that(get_data(hm,key_three) == placeholder);
remove_data(hm,key_three,NULL);
assert_ptr_equals(get_data(hm,key_three),NULL);
assert_true((int*)get_data(hm,key_three)==NULL);
//delete_hashmap(hm, destroy);
}
int main(){
test1();
return 0;
}

至少这些问题:

分配错误导致UB

(hm->items)[index]->data = (Data *)malloc(sizeof(Data *));      

我怀疑OP被通缉

(hm->items)[index]->data = (Data *)malloc(sizeof(Data));

避免大小错误,分配给被引用对象。不需要强制转换

(hm->items)[index]->data = malloc(sizeof (hm->items)[index]->data[0]);

(hm->items)[index] = (HashMapItem *)malloc(sizeof(HashMapItem *));
(hm->items)[index]->data = (Data *)malloc(sizeof(Data *));
hm->items = (HashMapItem **) calloc(key_space, sizeof(HashMapItem**)); 

悬空指针

@n。m.在remove_data中有一个错误,将(hm->items)[index]悬空在free之后

相关内容

最新更新