港式五张第一天问题:1.free函数;2.字节问题;3.宏定义;4.free高阶指针

GAME_STATUS getCombinedInfo(_OUT_ char**** combinedInfo)
{
	*combinedInfo = (char***)malloc(2 * sizeof(char**));
	if (*combinedInfo)
	{
		(*combinedInfo)[0] = (char**)malloc(COUNT_OF_NUM * sizeof(char*));
		(*combinedInfo)[1] = (char**)malloc(COUNT_OF_COLOR * sizeof(char*));
	}
	if (*combinedInfo && (*combinedInfo)[0])
	{
		for (int j = 0; j < COUNT_OF_NUM; j++)
		{
			(*combinedInfo)[0][j] = (char*)malloc(BYTES_FOR_SINGLE_NUM * sizeof(char));
		}
	}
	if (*combinedInfo && (*combinedInfo)[1])
	{
		for (int j = 0; j < COUNT_OF_COLOR; j++)
		{
			(*combinedInfo)[1][j] = (char*)malloc(BYTES_FOR_SINGLE_COLOR * sizeof(char));
		}
	}
	char* Card_NUM_8 = (char*)"8\0";
	char* Card_NUM_9 = (char*)"9\0";
	char* Card_NUM_10 = (char*)"10";
	char* Card_NUM_J = (char*)"J\0";
	char* Card_NUM_Q = (char*)"Q\0";
	char* Card_NUM_K = (char*)"K\0";
	char* Card_NUM_A = (char*)"A\0";
	char* Card_COLOR_梅花 = (char*)"梅花";
	char* Card_COLOR_黑桃 = (char*)"黑桃";
	char* Card_COLOR_红桃 = (char*)"红桃";
	char* Card_COLOR_方片 = (char*)"方片";
	if (*combinedInfo && (*combinedInfo)[0] && (*combinedInfo)[0][0] && (*combinedInfo)[0][1] && (*combinedInfo)[0][2] && (*combinedInfo)[0][3] && (*combinedInfo)[0][4] && (*combinedInfo)[0][5] && (*combinedInfo)[0][6])
	{
		memcpy((*combinedInfo)[0][0], Card_NUM_8, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][1], Card_NUM_9, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][2], Card_NUM_10, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][3], Card_NUM_J, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][4], Card_NUM_Q, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][5], Card_NUM_K, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][6], Card_NUM_A, BYTES_FOR_SINGLE_NUM);
	}
	if (*combinedInfo && (*combinedInfo)[1] && (*combinedInfo)[1][0] && (*combinedInfo)[1][1] && (*combinedInfo)[1][2] && (*combinedInfo)[1][3])
	{
		memcpy((*combinedInfo)[1][0], Card_COLOR_梅花, BYTES_FOR_SINGLE_COLOR);
		memcpy((*combinedInfo)[1][1], Card_COLOR_黑桃, BYTES_FOR_SINGLE_COLOR);
		memcpy((*combinedInfo)[1][2], Card_COLOR_红桃, BYTES_FOR_SINGLE_COLOR);
		memcpy((*combinedInfo)[1][3], Card_COLOR_方片, BYTES_FOR_SINGLE_COLOR);
	}
	return STATUS_SUCCESS;
}

1.malloc返回的地址千万千万不要暴力赋值!!!!!!!否则无法进行FREE!!!!!

对malloc返回的地址进行赋值:《《要用“温柔地”memcpy函数》》而不是暴力的address_from_malloc = other_address!!!!!FREE不了的时候够你哭的!!!

2.为什么"梅花"这个东西是char [7]呢?目前还不理解,但是不影响写代码(伟大的编译器!)!

3.字节问题.

(*combinedInfo)[0] = (char**)malloc(COUNT_OF_NUM * sizeof(char*));

这个东西因为要存储7张牌,那么就是7个地址,COUNT_OF_ NUM = 7没问题

但是

(*combinedInfo)[0][j] = (char*)malloc(BYTES_FOR_SINGLE_NUM * sizeof(char));

这个东西要存卡牌的牌面,因为“10”的存在所以每张卡片的牌面用两个char来表示:

1).如果是8 9 J Q K A,那么他们本身加上一个 \0 来存;

2).如果是10, 那就是它本身。

关键在于传入到malloc的字节数要比实际存储的字节数加一,因为要考虑到\0!因此malloc要传3而不是2!!!!!

传了2没有任何语法错误,没有任何警告。但是程序有的时候没问题,有的时候有问题!

也就是一个程序会运行出多个结果!

此外,在LEETCODE上面用C语言写东西,如果报错也绝大多数都是这里出了问题!!!!!!!!!!!!!!!!!!!!!

4.宏

宏中用printf打印宏串,(status)表达式将status视为一个数字,而#status表达式将status是为一个%s.

a ## b 表达把a和b连接起来!

5.free函数释放高阶指针

GAME_STATUS killCombinedInfoMemory(_OUT_ char**** combinedInfo)
{
	for (int j = 0; j < COUNT_OF_NUM; j++)
	{
		ExFreeMemoryToNULL(&((*combinedInfo)[0][j]));
	}
	for (int j = 0; j < COUNT_OF_COLOR; j++)
	{
		ExFreeMemoryToNULL(&((*combinedInfo)[1][j]));
	}
	for (int j = 0; j < 2; j++)
	{
		(*combinedInfo)[j] = NULL;
	}
	*combinedInfo = NULL;
	return STATUS_SUCCESS;
}
void ExFreeMemoryToNULL(PVOID* mem)
{
	free(*mem);
	*mem = NULL;
}
#define TEST_MEMORY(address) \
do\
{\
	if((ULONG)(address) == 0) \
	{\
		printf("Address: %s is NULL\n", #address);\
	}\
	else\
	{\
		printf("Address: %s exists\n", #address);\
	}\
}while(0);

0).free只能释放由malloc以及malloc派生的函数返回的地址!

1).(假设p=malloc(8);)由上一条,free某个指针会从p所指向的字节开始,一直查8个字节,并把这些字节换为DD.(在VS2022编译器,x86,windows10系统上是这样);

2).我封装的这个ExFreeMemoryToNULL,在第一步完成之后还会把这个指针变成0x00000000(x86系统下一个指针4个字节)因为指针本质上还是一个数,x86下是4字节ULONG, x64下是8字节ULONG64而已;

3).函数内修改指针指向的值,要传指针的地址,这也是为什么在ExFreeMemoryToNULL中传的是二级指针;

4).多级指针释放逻辑:

①->先用根指针导到边缘指针(就是在解引用一次就是单个的结构成员或者字符了,在这里就是从*combinedInfo导到combinedInfo[0][j]和combinedInfo[1][j])。

导到边缘之后,ExFreeMemoryToNULL掉他们:

for (int j = 0; j < COUNT_OF_NUM; j++)
{
	ExFreeMemoryToNULL(&((*combinedInfo)[0][j]));
}
for (int j = 0; j < COUNT_OF_COLOR; j++)
{
	ExFreeMemoryToNULL(&((*combinedInfo)[1][j]));
}

因为这里传递的是四级指针,那么显然combinedInfo前面要加一个*才和一般语义的combinedInfo相同;又因为ExFreeMemoryToNULL要传递指针的地址来进行函数内修改指针所指向的值,所以前面还要加&;

②->把边缘指针ExFreeMemoryToNULL掉之后,剩下的高阶指针依次设置为NULL即可。

for (int j = 0; j < 2; j++)
{
	(*combinedInfo)[j] = NULL;
}
*combinedInfo = NULL;

③.初始状态如下:

④.释放完之后如下:

目前卡片的源文件cardFunctions.c

#include "showHandCardDefs.h"
char* g_initialCardNum = (char*)"0\0";
char* g_initialCardColor = (char*)"无花";
GAME_STATUS initialCard(_OUT_ PCard* card, _IN_ char* num, _IN_ char* color)
{
	*card = (PCard)malloc(sizeof(Card));
	if (*card)
	{
		(*card)->num = (char*)malloc(BYTES_FOR_SINGLE_NUM * sizeof(char));
		if ((*card)->num)
		{
			memcpy((*card)->num, num, BYTES_FOR_SINGLE_NUM);
		}
		(*card)->color = (char*)malloc(BYTES_FOR_SINGLE_COLOR * sizeof(char));
		if ((*card)->color)
		{
			memcpy((*card)->color, color, BYTES_FOR_SINGLE_COLOR);
		}
	}
	return STATUS_SUCCESS;
}
GAME_STATUS initialSentCardsStack(_OUT_ PCard** stack)
{
	*stack = (PCard*)malloc(MAX_POSSIBLE_CARDS * sizeof(PCard));
	if (*stack)
	{
		for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
		{
			(*stack)[j] = (PCard)malloc(sizeof(Card));
		}
		for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
		{
			if((stack[j]) != NULL)
			{
				((*stack)[j])->num = (char*)malloc(BYTES_FOR_SINGLE_NUM * sizeof(char));
				((*stack)[j])->color = (char*)malloc(BYTES_FOR_SINGLE_COLOR * sizeof(char));
			}
		}
		for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
		{
			if ((*((*stack) + j)) != NULL)
			{
				if ((*stack)[j]->num && (*stack)[j]->color && g_initialCardNum && g_initialCardColor)
				{
					memcpy(((*stack)[j])->num, g_initialCardNum, BYTES_FOR_SINGLE_NUM);
					memcpy(((*stack)[j])->color, g_initialCardColor, BYTES_FOR_SINGLE_COLOR);
				}
			}
		}
	}
	return STATUS_SUCCESS;
}
GAME_STATUS getCombinedInfo(_OUT_ char**** combinedInfo)
{
	*combinedInfo = (char***)malloc(2 * sizeof(char**));
	if (*combinedInfo)
	{
		(*combinedInfo)[0] = (char**)malloc(COUNT_OF_NUM * sizeof(char*));
		(*combinedInfo)[1] = (char**)malloc(COUNT_OF_COLOR * sizeof(char*));
	}
	if (*combinedInfo && (*combinedInfo)[0])
	{
		for (int j = 0; j < COUNT_OF_NUM; j++)
		{
			(*combinedInfo)[0][j] = (char*)malloc(BYTES_FOR_SINGLE_NUM * sizeof(char));
		}
	}
	if (*combinedInfo && (*combinedInfo)[1])
	{
		for (int j = 0; j < COUNT_OF_COLOR; j++)
		{
			(*combinedInfo)[1][j] = (char*)malloc(BYTES_FOR_SINGLE_COLOR * sizeof(char));
		}
	}
	char* Card_NUM_8 = (char*)"8\0";
	char* Card_NUM_9 = (char*)"9\0";
	char* Card_NUM_10 = (char*)"10";
	char* Card_NUM_J = (char*)"J\0";
	char* Card_NUM_Q = (char*)"Q\0";
	char* Card_NUM_K = (char*)"K\0";
	char* Card_NUM_A = (char*)"A\0";
	char* Card_COLOR_梅花 = (char*)"梅花";
	char* Card_COLOR_黑桃 = (char*)"黑桃";
	char* Card_COLOR_红桃 = (char*)"红桃";
	char* Card_COLOR_方片 = (char*)"方片";
	if (*combinedInfo && (*combinedInfo)[0] && (*combinedInfo)[0][0] && (*combinedInfo)[0][1] && (*combinedInfo)[0][2] && (*combinedInfo)[0][3] && (*combinedInfo)[0][4] && (*combinedInfo)[0][5] && (*combinedInfo)[0][6])
	{
		memcpy((*combinedInfo)[0][0], Card_NUM_8, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][1], Card_NUM_9, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][2], Card_NUM_10, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][3], Card_NUM_J, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][4], Card_NUM_Q, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][5], Card_NUM_K, BYTES_FOR_SINGLE_NUM);
		memcpy((*combinedInfo)[0][6], Card_NUM_A, BYTES_FOR_SINGLE_NUM);
	}
	if (*combinedInfo && (*combinedInfo)[1] && (*combinedInfo)[1][0] && (*combinedInfo)[1][1] && (*combinedInfo)[1][2] && (*combinedInfo)[1][3])
	{
		memcpy((*combinedInfo)[1][0], Card_COLOR_梅花, BYTES_FOR_SINGLE_COLOR);
		memcpy((*combinedInfo)[1][1], Card_COLOR_黑桃, BYTES_FOR_SINGLE_COLOR);
		memcpy((*combinedInfo)[1][2], Card_COLOR_红桃, BYTES_FOR_SINGLE_COLOR);
		memcpy((*combinedInfo)[1][3], Card_COLOR_方片, BYTES_FOR_SINGLE_COLOR);
	}
	return STATUS_SUCCESS;
}
GAME_STATUS verifyCardAlreadySent(_IN_ PCard card, _IN_ PCard* stack, _OUT_ INT* flag, _OUT_ INT* loc)
{
	*flag = 1;
	*loc = 0;
	for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
	{
		if (strncmp(stack[j]->num, card->num, BYTES_FOR_SINGLE_NUM) == 0)
		{
			if (strncmp(stack[j]->color, card->color, BYTES_FOR_SINGLE_COLOR) == 0)
			{
				*flag = 0;
				*loc = j;
			}
		}
	}
	return STATUS_SUCCESS;
}
GAME_STATUS pushCardIntoStack(_IN_ PCard card, _IN_OUT_ PCard* stack)
{
	int top = 0;
	for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
	{
		if(*(stack[j]->num) == '0')
		{
			top = j;
			break;
		}
	}
	memcpy(stack[top]->num, card->num, BYTES_FOR_SINGLE_NUM);
	memcpy(stack[top]->color, card->color, BYTES_FOR_SINGLE_COLOR);
	return STATUS_SUCCESS;
}
GAME_STATUS displaySentStackValid(_IN_ PCard* stack)
{
	for (int j = 0; *(stack[j]->num) != '0'; j++)
	{
		printf("%ld -> %s%s\n", j + 1, stack[j]->color, stack[j]->num);
	}
	return STATUS_SUCCESS;
}
GAME_STATUS displayAllStack(_IN_ PCard* stack)
{
	for (int j = 0; j<MAX_POSSIBLE_CARDS; j++)
	{
		printf("%ld -> %s%s\n", j + 1, stack[j]->color, stack[j]->num);
	}
	return STATUS_SUCCESS;
}
GAME_STATUS clearSentCardsStack(_IN_OUT_ PCard* stack)
{
	for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
	{
		memcpy(stack[j]->num, g_initialCardNum, BYTES_FOR_SINGLE_NUM);
		memcpy(stack[j]->color, g_initialCardColor, BYTES_FOR_SINGLE_COLOR);
	}
	return STATUS_SUCCESS;
}
GAME_STATUS killCardMemory(_OUT_ PCard* card)
{
	ExFreeMemoryToNULL(&((*card)->num));
	ExFreeMemoryToNULL(&((*card)->color));
	*card = NULL;
	return STATUS_SUCCESS;
}
GAME_STATUS killStackMemory(_OUT_ PCard** stack)
{
	for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
	{
		ExFreeMemoryToNULL(&(((*stack)[j])->num));
	}
	for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
	{
		ExFreeMemoryToNULL(&(((*stack)[j])->color));
	}
	for (int j = 0; j < MAX_POSSIBLE_CARDS; j++)
	{
		(*stack)[j] = NULL;
	}
	*stack = NULL;
	return STATUS_SUCCESS;
}
GAME_STATUS killCombinedInfoMemory(_OUT_ char**** combinedInfo)
{
	for (int j = 0; j < COUNT_OF_NUM; j++)
	{
		ExFreeMemoryToNULL(&((*combinedInfo)[0][j]));
	}
	for (int j = 0; j < COUNT_OF_COLOR; j++)
	{
		ExFreeMemoryToNULL(&((*combinedInfo)[1][j]));
	}
	for (int j = 0; j < 2; j++)
	{
		(*combinedInfo)[j] = NULL;
	}
	*combinedInfo = NULL;
	return STATUS_SUCCESS;
}

三个头文件

//showHandDefs.h
#pragma once
#ifndef __showHandDefs__
#define __showHandDefs__
#endif 

//公共库库头文件区域↓
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
//公共库库头文件区域↑
//类型定义↓
typedef int GAME_STATUS;
//类型定义↑
//结构定义↓
typedef struct _Card
{
	char* num;
	char* color;
}Card, * PCard;
//结构定义↑

//形参属性宏定义↓
#ifndef _IN_
#define _IN_
#endif
#ifndef _OUT_
#define _OUT_
#endif
#ifndef _IN_OUT_
#define _IN_OUT_
#endif
//形参属性宏定义↑
// 
//卡牌属性宏定义↓
#define COUNT_OF_NUM 7
#define COUNT_OF_COLOR 4
#define BYTES_FOR_SINGLE_NUM 3
#define BYTES_FOR_SINGLE_COLOR 7
#define MAX_POSSIBLE_CARDS 25
//卡牌属性宏定义↑
// 
//错误代码宏定义↓
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS 0
#endif
#define MEMORY_FAILED_ALLOCATE 0x00000001
#define INVALID_STACK_LOCATION 0x00000002
#define NULL_MEMORY_INPUT 0x00000003
//错误代码宏定义↑
// 
//功能宏定义↓
#define merge(sta1, sta2) (sta1 ## sta2)
#define CHECK_RETURN_WITH_STATUS(status) \
do\
{\
	if((status) != 0x0)\
	{\
		printf("Operation: %s Failed. Error Code: %ld\n", #status, (status));\
	}\
	else\
	{\
		printf("Operation: %s Successfully. Returned code: %ld\n", #status, (status));\
	}\
}while(0);
#define TEST_MEMORY(address) \
do\
{\
	if((ULONG)(address) == 0) \
	{\
		printf("Address: %s is NULL\n", #address);\
	}\
	else\
	{\
		printf("Address: %s exists\n", #address);\
	}\
}while(0);
//功能宏定义↑
//showHandCardDefs.h
#ifndef __showHandCardDefs__
#define __showHandCardDefs__
#include "showHandDefs.h"
GAME_STATUS initialCard(_OUT_ PCard* card, _IN_ char* num, _IN_ char* color);
GAME_STATUS initialSentCardsStack(_OUT_ PCard** stack);
GAME_STATUS getCombinedInfo(_OUT_ char**** combinedInfo);
GAME_STATUS verifyCardAlreadySent(_IN_ PCard card, _IN_ PCard* stack, _OUT_ INT* flag, _OUT_ INT* loc);
GAME_STATUS pushCardIntoStack(_IN_ PCard card, _IN_OUT_ PCard* stack);
GAME_STATUS displaySentStackValid(_IN_ PCard* stack);
GAME_STATUS displayAllStack(_IN_ PCard* stack);
GAME_STATUS clearSentCardsStack(_IN_OUT_ PCard* stack);
GAME_STATUS killCardMemory(_OUT_ PCard* card);
GAME_STATUS killStackMemory(_OUT_ PCard** stack);
GAME_STATUS killCombinedInfoMemory(_OUT_ char**** combinedInfo);
#endif
//showHandPublicDefs.h
#ifndef __showHandPublicDefs__
#define __showHandPublicDefs__
#include "showHandDefs.h"
void ExFreeMemoryToNULL(PVOID* mem);
#endif

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值