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

我想读一个ANSI格式的文件,并将其转换为binary.I'm声明两个像这样的dynamic内存分配: char* binary_reverse = new char;char * binary = new char;

debugging时,我看到这(二进制)包含太多的垃圾值。 为什么这样?

我删除这些像:delete binary_reverse; 删除二进制; 但是,在删除它给我错误:

'ASCIItoBinary.exe':加载'D:\ TryingBest \ Reactice \ ASCIItoBinary \ Debug \ ASCIItoBinary.exe',加载符号。 'ASCIItoBinary.exe':加载'C:\ Windows \ SysWOW64 \ ntdll.dll',找不到或打开PDB文件'ASCIItoBinary.exe':加载'C:\ Windows \ SysWOW64 \ kernel32.dll',无法find或打开PDB文件'ASCIItoBinary.exe':Loaded'C:\ Windows \ SysWOW64 \ KernelBase.dll',找不到或打开PDB文件'ASCIItoBinary.exe':Loaded'C:\ Windows \ SysWOW64 \ msvcr100d.dll' ,符号加载。 HEAP [ASCIItoBinary.exe]:在00241ED0修改00241EFD的堆块过去请求的大小为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命令分配一个字符。 你想分配更多,使用new char[9] 。 由于您最多打印了8位,因此您需要为空终止符添加一个额外的字符。 请务必在字符串的末尾设置binary_reverse[y]=0

然后delete[]而不是delete

但是说,你应该使用std::stringstd::vector来代替…

结果发现在这里有一堆东西是错误的,几乎所有这些都是由于没有终止输出字符串,然后在错误的方向上寻找修复。

我将忽略错误

 char* binary_reverse = new char; 

除了说OP需要更多的存储。

 char* binary_reverse = new char[8]; 

正确的做法是返回到OP开始的临时分配,并添加一个额外的字节来包含字符串的空终止符。 然后使用这个空格作为空终止符。

没有空终止符,你没有一个字符串。 你有一个二进制的blob。 打印例程,所有的c风格的字符串例程,依靠那个终结者。 没有它,他们不知道绳子在哪里结束,并进入寻找它的野生蓝色的那边。 往往坏事发生。 或者也许没有。 当你走出一个数组时,会发生什么情况是不确定的。 也许它做你想要的。 也许它没有。 没办法确定。 在这种情况下,从轨道上删除站点甚至不起作用。

所以分配临时存储:

 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被构造并且被转换成binarybinary需要被终止而变成一个字符串,而不仅仅是另一个匿名二进制的blob。

 binary[8] = '\0'; 

现在可以打印了。

建议:

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

如果OP没有注释到打印语句的可能性是好的,昨天晚上有人会发现主要的bug。 尽量减少代码是好的,但OP删除了错误的可见表现形式。

这个代码可以大大简化。 你知道你需要8位,因为你在ascii中工作(实际上,ascii是7位,但除了8位以外很少见)。 将while (ascii != 1)转换for (int count = 0; count < 8; count++)并测试字符中的所有8位。 稍后保存你几圈,因为现在你总是得到8位。