如何停止功能的内存泄漏

时间:2019-05-05 15:54:20

标签: c++ arrays

tl; dr:如何将无符号的32位整数转换为不带随机文本的chars / uint8_t

好的,我愿意为此牺牲一些声誉。我需要快速将4字节无符号整数转换为数组字节,以便读取/写入/操作自己结构的二进制文件。
这样我就可以读取一个结构,然后将其用作对象,而不是读取它,而是每次更改都写入其中。

但是当我尝试实现一个功能时,我会泄漏。指针只是不断将值添加到函数范围之外。

void trans_byte( uint32_t &A, uint8_t *out ){
    // i did this with loop too same thing happens
    uint8_t *ptr = (uint8_t*)&A;
    out[3] = *ptr;
    ptr++;
    out[2] = *ptr;
    ptr++;
    out[1] = *ptr;
    ptr++;
    out[0] = *ptr;
    ptr = ptr - 4;
}

uint32_t trans_ray( uint8_t *in ){
    return ( in[0] << 24 ) | ( in[1] << 16 ) | ( in[2] << 8 ) | in[3]; 
}

在主要方面:

int main(){
    std::cout << "SHUGA" << std::endl; // test printing to see if test works 

    uint32_t ADR = 0x6D4E4344; // memory should write magic of mNCD

    uint8_t ret[4];// array to be "outed" from function
    trans_byte(ADR, ret); // function
    uint8_t ret2[4] = { ret[0], ret[1], ret[2], ret[3] }; //copy of array to see if issue happens if i copy it

    std::cout << ret << std::endl; // printing the array 1
    std::cout << ret2 << std::endl; // printing the array 2
}

然后输出:

SHUGA
mNCDmNCD // keep in mind I called the function only once. 
mNCD

添加到主页面后

std::cout << "shiya" << std::endl;
uint32_t ADR2 = trans_ray(ret);

std::cout << ret << std::endl;
std::cout << ret2 << std::endl;
std::cout << (ret==ret2) << std::endl;

然后我得到了这个可爱的烂摊子:

SHUGA
mNCDmNCD─[uÉ@
mNCD─[uÉ@
shiya
mNCDmNCD─[uÉ@
mNCD─[uÉ@
0

所以我猜测这是某种形式的内存泄漏,并且指针会在以后继续读取内存或其他内容(因此会有过多的符号)。

那么,如何在没有指针继续读取和操作数组的情况下进行从uint32_tuint8_t的来回转换?

在开始评论之前:
我不想使用std::vector,因为我不想将每个文件另外的20kb左右的二进制数据添加到现有的大型项目中,无论是文件还是PE。
我不能使用std::string,因为我不想寻找字符串结尾\x00
我尝试使用unions,但是字节是相反的,对于魔术数字和类似数字,我需要将它们按顺序排列。即使我尝试反转阵列,我仍然需要遇到这个问题。
我尝试使用struct-ures和class-es,但是当我在对象中更改某些内容并需要更新文件时,在编写代码块时仍然会遇到此问题。

2 个答案:

答案 0 :(得分:2)

 std::cout << ret

这需要以null结尾的字符串(信息here):

  

8)输出实现定义的字符串,就像通过* this << s来输出一样,其中s是一个以空字符结尾的字符串。

否则它将一直打印,直到找到\0

这就是为什么我们使用向量,字符串等的原因。忘记了所有这种C风格的1980年代的编程。除非您正在使用20KB RAM编程某些超级微控制器,否则内存应该不是问题。

答案 1 :(得分:1)

  

如何将无符号的32位整数转换为不带随机文本的chars / uint8_t

您可以为此union,但必须阅读有关Endianness的信息。试试这个:

#include <stdint.h>

union {
    uint32_t _32ui;
    uint8_t _8ui[4];
}
  

我尝试使用联合,但是字节是相反的,对于魔术数字和类似数字,我需要将它们按顺序排列。即使我尝试反转阵列,我仍然需要遇到这个问题。

有些功能可以按uint32_tbig-endian顺序转换little-endian。我不确定您的操作系统,处理器和编译器。但是Linux可以使用类似htonl的功能。

  

所以我猜测这是某种形式的内存泄漏,并且指针会在以后继续读取内存或其他内容(因此会有过多的符号)。

不。这不是问题。您不会在程序中分配任何会导致内存泄漏的内存,也不会超出分配的内存缓冲区。问题在于您没有阅读过std::cout文档,而您可能已经忽略了compiler's warnings

std::cout已被C样式字符串重载,并且期望null-terminated字符数组。但是您尚未提供以Null结尾的字符数组。我建议写一个简单的函数来打印数组。

void printArray(uint8_t *array, size_t size)
{
    for (size_t i = 0; i < size; i++)
        std::cout << array[i];
    std::cout << std::endl;
}