Huffman编码

本文介绍了一种Huffman编码算法的C++实现,并详细解释了如何处理Visual Studio 2019编译时出现的C6385和C6386警告。通过使用#pragma warning指令,解决了编译器的误报问题,确保了代码的正确性和警告提示的管理。
摘要由CSDN通过智能技术生成

Huffman.h

#pragma once
#ifndef HUFFMAN_H
#define HUFFMAN_H
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(push)
#pragma warning(disable:6385)
#pragma warning(disable:6386)
#include <stdio.h>
#include <iostream>

using namespace std;

typedef struct
{
	int weight;
	int parent, lchild, rchild;
}HTNode,*HuffmanTree;
typedef char** HuffmanCode;

#endif

Huffman.cpp

#include "huffman.h"

void Select(HuffmanTree& HT, int n, int s1, int s2)
{

}

void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, int* w, int n)
{
	if (n <= 1)
		return;
	int m = 2 * n - 1;
	//HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
	HT = new HTNode[m+1];        //0号单元未用

	int i;
	HTNode* p;
	int s1=1, s2=2;
	for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++w)
		*p = { *w,0,0,0 };
	for (; i <= m; ++i, ++p)
		*p = { 0,0,0,0 };
	for (i = n + 1; i <= m; ++i)
	{
		Select(HT, i - 1, s1, s2);        //在HT[1...i-1]找到parent为0权重最小的两个结点
		HT[s1].parent = HT[s2].parent = i;
		HT[i].lchild = s1;      HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}

	//从叶子到根逆向求Huffman编码
	HC = new char*;
	char* cd = new char[n];
	int c, f;
	cd[n - 1] = '\0';

	for (i = 1; i <= n; ++i)
	{
		int start = n - 1;
		for (c = i, f = HT[i].parent; f != 0; c=f,f = HT[f].parent)
		{
			if (HT[f].lchild == c)
				cd[--start] = '0';
			else
				cd[--start] = '1';
		}
		HC[i] = new char;
		strcpy(HC[i], &cd[start]);
	}
	delete[] cd;
}

void HuffmanCoding2(HuffmanTree& HT, HuffmanCode& HC, int* w, int n)
{
	if (n <= 1)
		return;
	int m = 2 * n - 1;
	//HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
	HT = new HTNode[m + 1];        //0号单元未用

	int i;
	HTNode* p;
	int s1 = 1, s2 = 2;
	for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++w)
		*p = { *w,0,0,0 };
	for (; i <= m; ++i, ++p)
		*p = { 0,0,0,0 };
	for (i = n + 1; i <= m; ++i)
	{
		Select(HT, i - 1, s1, s2);        //在HT[1...i-1]找到parent为0且权重最小的两个结点
		HT[s1].parent = HT[s2].parent = i;
		HT[i].lchild = s1;      HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}

	//无栈非递归遍历Huffman树,从根结点开始遍历
	HC = new char*;
	int q = m, cdlen = 0;
	char* cd = new char;

	//cd = (char*)malloc(n * sizeof(char));
	//cd[n - 1] = "\0";

	for (i = 1; i <= m; ++i)
		HT[i].weight = 0;
	while (q)
	{
		if (HT[q].weight == 0)      //向左
		{
			HT[q].weight = 1;
			if (HT[q].lchild)
			{
				cd[cdlen++] = '0';
				q = HT[q].lchild;
			}
			else
			{
				HC[q] = new char;
				cd[cdlen] = '\0';
				strcpy(HC[q], cd);
			}
		}
		else if (HT[q].weight == 1)
		{
			HT[q].weight = 2;
			if (HT[q].lchild)
			{
				q = HT[q].rchild;
				cd[cdlen++] = '1';
			}
		}
		else
		{
			HT[q].weight = 0;
			q = HT[q].parent;
			--cdlen;
		}
	}
}

注:在Visual Studio2019中,在进行编译时出现了这样的警告:

  1. C6385:从…中读取的数据无效: 可读大小为…个字节,但可能读取了…个字节;

  2. C6386:从…中写入到…时缓冲区溢出: 可写大小为…个字节,但可能写入了…个字节

微软在默认情况下强制对C和C++代码强制使用SAL分析,除了以上两种警告外,还有其他的一些误报(false positive)。

解决方法

#pragma warning(push)是保存当前的编译器警告状态;
#pragma warning(pop)是恢复原先的警告状态。

#pragma warning(push)
#pragma warning(disable:6385)
#pragma warning(disable:6386)
/*Source Code*/
#pragma   warning(pop)  

这样在编译Source Code部分的代码时,6385、6386警告将不会出现。

也可以不加#pragma warning(push)和#pragma warning(pop),这样#pragma warning(disable:6385)和#pragma warning(disable:6386)将在全局生效。

C6385,C6386警告的原文链接:https://www.cnblogs.com/csgo-416482145/p/13828845.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值