新声明在使用delete时包含垃圾值和堆损坏



我正在尝试读取一个ANSI格式的文件,并将其转换为二进制文件。我声明两个动态内存分配如下:char* binary_reverse = new char;char * binary = new char;

在调试时,我看到这个(二进制)包含太多垃圾值。为什么会这样?

我正在删除以下内容:delete binary_reverse;删除二进制;然而,在删除过程中,它给了我错误:

'ASCIItoBinary.exe‘:已加载‘D:\TryingBest\Reactive\ASCIItoBinary\Debug\ASCIToBinary.exe’,已加载符号。"ASCIItoBinary.exe":已加载"C:\Windows\SysWOW64\ntdll.dll",找不到或打开PDB文件"ASCIItoBinary.exe":已加载"C:\Windows\SysWOW64\kernel32.dll",找不到或打开PDB文件"ASCIItoBinary.exe":已加载"C:\Windows\SysWOW64\KernelBase.dll",找不到或打开PDB文件"ASCIItoBinary.exe":已加载"C:\Windows\SysWOW64\msvcr100d.dll",已加载符号。HEAP[ASCIToBinary.exe]:在00241EFD修改的00241ED0处的堆块超过了请求的25大小Windows在ASCIItoBinary.exe中触发了断点。

以下是我如何执行代码:

#include <cstring>
void AtoB(char * input)
{
unsigned int ascii; //used to store ASCII number of a character
unsigned int length = strlen(input);
//cout << " ";
for (int x = 0; x < length; x++) //repeat until the input is read
{
ascii = input[x];
char* binary_reverse = new char;       //dynamic memory allocation
char * binary = new char;
//char binary[8];
int y = 0;
while (ascii != 1)
{
if (ascii % 2 == 0)    //if ascii is divisible by 2
{
binary_reverse[y] = '0';   //then put a zero
}
else if (ascii % 2 == 1)    //if it isnt divisible by 2
{
binary_reverse[y] = '1';   //then put a 1
}
ascii /= 2;    //find the quotient of ascii / 2
y++;    //add 1 to y for next loop
}
if (ascii == 1)    //when ascii is 1, we have to add 1 to the beginning
{
binary_reverse[y] = '1';
y++;
}
if (y < 8)  //add zeros to the end of string if not 8 characters (1 byte)
{
for (; y < 8; y++)  //add until binary_reverse[7] (8th element)
{
binary_reverse[y] = '0';
}
}
for (int z = 0; z < 8; z++)  //our array is reversed. put the numbers in the rigth order (last comes first)
{
binary[z] = binary_reverse[7 - z];
}
//printf("the Binary is %s",binary);
//cout << binary;   //display the 8 digit binary number
delete binary_reverse;     //free the memory created by dynamic mem. allocation
delete binary;
}
}

我想要"二进制"中的精确二进制值。不是二进制值和垃圾?如何消除垃圾值?如何避免堆损坏?

问题是new char命令只分配了1个字符。您希望使用new char[9]分配更多。由于您最多打印出8位,因此需要为null终止符添加一个额外的字符。请确保在字符串末尾设置binary_reverse[y]=0

然后用CCD_ 6代替CCD_。

但也就是说,您应该使用std::stringstd::vector。。。

发现这里有很多错误,几乎所有这些都源于没有终止输出字符串,然后朝着错误的方向寻找解决方案。

我将忽略中的错误

char* binary_reverse = new char;

而不是说OP需要更多的存储。

char* binary_reverse = new char[8];

正确的方法是回到OP开始时的临时分配,并添加一个额外的字节来包含字符串的null终止符。然后将该空间用作null终止符。

如果没有null终止符,就没有字符串。您有一个二进制blob。打印例程,所有c样式的字符串例程,都依赖于存在的终止符。如果没有它,他们就不知道绳子的尽头在哪里,然后去那边的蓝色荒野寻找它。坏事经常发生。或者可能没有。当你走出一个数组时会发生什么是未定义的。也许它能满足你的需求。也许没有。没有办法确定。在这种情况下,从轨道上对站点进行Nuking甚至都不起作用。

所以分配临时存储:

char binary_reverse[8]; // not using this one like a string so we don't need a terminator
char binary[9]; // printing this one. Need a terminator to know when to stop printing.

稍后,在构造binary_reverse并将其传输到binary之后,binary需要被终止以成为字符串,而不仅仅是另一个匿名二进制blob。

binary[8] = '';

现在可以打印了。

建议:

Visual Studio有一个很棒的调试器。熟悉它。它会为你节省很多时间。

如果OP没有对打印报表发表评论,很可能有人会在昨晚发现主要错误。最小化代码是好的,但是OP删除了可见的bug表现。

这个代码可以大大简化。你知道你想要8位,因为你在使用ascii(嗯,实际上ascii是7位,但现在很少看到除了8位之外的任何东西)。将while (ascii != 1)转换为for (int count = 0; count < 8; count++),并测试字符中的所有8位。以后为您节省几个循环,因为现在您总是得到8位。

最新更新