Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ ARM GCC堆未完全使用_C++_C_Gcc_Arm_Heap - Fatal编程技术网

C++ ARM GCC堆未完全使用

C++ ARM GCC堆未完全使用,c++,c,gcc,arm,heap,C++,C,Gcc,Arm,Heap,我正在设置Cortex-M4平台以使用堆内存,但遇到了一些问题。 我将堆区域大小设置为512字节,它只分配9个字节。然后我将heap设置为10kB,它只能分配362个字节。 这是我的gcc存根: int _sbrk(int a) { //align a to 4 bytes if (a & 3) { a += (4 - (a & 0x3)); } extern long __heap_start__; extern

我正在设置Cortex-M4平台以使用堆内存,但遇到了一些问题。 我将堆区域大小设置为512字节,它只分配9个字节。然后我将heap设置为10kB,它只能分配362个字节。 这是我的gcc存根:

int _sbrk(int a)
{
    //align a to 4 bytes
    if (a & 3)
    {
        a += (4 - (a & 0x3));
    }

    extern long __heap_start__;
    extern long __heap_end__;
    static char* heap_ptr = (char*)&__heap_start__;

    if (heap_ptr + a < (char*)&__heap_end__)
    {
        int res = (int)heap_ptr;
        heap_ptr += a;
        return res;
    }
    else
    {
        return -1;
    }
}
我该怎么做才能让它使用完整的堆内存?如何计算参数?基本上,这里怎么了

编译C++代码,使用<代码>新(STD:NoFooP)< /C> > /P> 编辑 如果我使用的是

malloc
(C样式),它会在main之前分配524字节,并且不会调用
\u sbrk
,这与使用
操作符new
时不同

arm-none-eabi-g++.exe (GNU Tools for ARM Embedded Processors 6-2017-q2-update) 6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437]
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EDIT2最小完整可验证示例
这是我的申请代码和带有信息打印的
\u sbrk

void foo()
{
    while (true)
    {
        uint8_t * byte = new (std::nothrow) uint8_t;
        if (byte)
        {
            DBB("Byte allocated");
            cnt++;
        }
        else
        {
            DBB_ERROR("Allocated %d bytes", cnt);
        }
    }
}

int _sbrk(int a)
{
    //align a to 4 bytes
    if (a & 3)
    {
        a += (4 - (a & 0x3));
    }

    extern long __heap_start__;
    extern long __heap_end__;
    static char* heap_ptr = (char*)&__heap_start__;

    DBB("%d 0x%08X", a, a);
    DBB("0x%08X", heap_ptr);
    DBB("0x%08X", &__heap_start__);
    DBB("0x%08X", &__heap_end__);

    if (heap_ptr + a < (char*)&__heap_end__)
    {
        int res = (int)heap_ptr;
        heap_ptr += a;
        DBB("OK 0x%08X 0x%08X", res, heap_ptr);
        return res;
    }
    else
    {
        DBB("ERROR");
        return -1;
    }
}
void foo()
{
while(true)
{
uint8_t*字节=新(std::nothrow)uint8_t;
if(字节)
{
DBB(“字节分配”);
cnt++;
}
其他的
{
DBB_错误(“已分配%d字节”,cnt);
}
}
}
int_sbrk(int a)
{
//将a对齐到4字节
如果(a&3)
{
a+=(4-(a&0x3));
}
外部长堆启动;
外部长堆端;
静态字符*堆ptr=(字符*)&堆启动;
DBB(“%d 0x%08X”,a,a);
DBB(“0x%08X”,堆\u ptr);
DBB(“0x%08X”,和堆启动);
DBB(“0x%08X”,和堆结束);
如果(堆ptr+a<(字符*)和堆结束)
{
int res=(int)heap_ptr;
堆_ptr+=a;
DBB(“确定0x%08X 0x%08X”,res,heap_ptr);
返回res;
}
其他的
{
DBB(“错误”);
返回-1;
}
}
生产量为:


你的输出显示C++内存分配系统首先要求32字节,然后是132字节。然后,它可以使用该空间满足九个对
新uint8\t
的请求。据推测,它使用164字节中的一些字节来保存内部记录。这可能涉及保留分配块的链接列表或映射,或某些其他数据结构。此外,为了提高效率,它可能不跟踪单字节分配,而是为每个分配提供一些最小块大小,可能是8或16字节。当它用完所需的空间时,它会请求另外4096字节。然后,您的
sbrk
将失败,因为这不可用

> C++内存分配系统的设计工作。为了操作,它需要的空间比分配给单个请求的空间要大。为了为请求提供更多内存,必须在堆中提供更多内存。从
sbrk
提供给内存分配系统的内存和从内存分配系统提供给其客户机的内存之间不可能存在一对一的对应关系或任何简单的对应关系

无法告诉C++内存分配系统使用“全堆内存”来满足它的请求。它需要跟踪内存的动态分配和释放。由于它的客户机可能会发出不同大小的请求,并且可能会以任何顺序释放它们,因此它需要能够跟踪当前分配了哪些块,哪些块没有分配——一个简单的堆栈是不够的。因此,它必须使用额外的数据结构来跟踪内存,而这些数据结构将占用空间。因此,并非所有堆空间都可以提供给客户端;其中一些必须用于开销


<>如果在C++实现中内存分配系统的使用效率太低,您可能会用自己编写的或用第三方软件来替换它。内存分配系统的任何实现都会对速度和块大小进行各种权衡,并且可以针对特定的情况和目标进行调整。

< P>您的输出显示C++内存分配系统首先要求32字节,然后是132字节。然后,它可以使用该空间满足九个对
新uint8\t
的请求。据推测,它使用164字节中的一些字节来保存内部记录。这可能涉及保留分配块的链接列表或映射,或某些其他数据结构。此外,为了提高效率,它可能不跟踪单字节分配,而是为每个分配提供一些最小块大小,可能是8或16字节。当它用完所需的空间时,它会请求另外4096字节。然后,您的
sbrk
将失败,因为这不可用

> C++内存分配系统的设计工作。为了操作,它需要的空间比分配给单个请求的空间要大。为了为请求提供更多内存,必须在堆中提供更多内存。从
sbrk
提供给内存分配系统的内存和从内存分配系统提供给其客户机的内存之间不可能存在一对一的对应关系或任何简单的对应关系

无法告诉C++内存分配系统使用“全堆内存”来满足它的请求。它需要跟踪内存的动态分配和释放。由于它的客户机可能会发出不同大小的请求,并且可能会以任何顺序释放它们,因此它需要能够跟踪当前分配了哪些块,哪些块没有分配——一个简单的堆栈是不够的。因此,它必须使用额外的数据结构来跟踪内存,而这些数据结构将占用空间。因此,并非所有堆空间都可以提供给客户端;其中一些必须用于开销

<>如果在C++实现中内存分配系统的使用效率太低,您可能会用自己编写的或用第三方软件来替换它。内存分配系统的任何实现都会在速度和块大小方面做出各种权衡,这些权衡可以根据特定情况和目标进行调整。

我得到一个以字节为单位的(参数)请求:void foo()
{
    while (true)
    {
        uint8_t * byte = new (std::nothrow) uint8_t;
        if (byte)
        {
            DBB("Byte allocated");
            cnt++;
        }
        else
        {
            DBB_ERROR("Allocated %d bytes", cnt);
        }
    }
}

int _sbrk(int a)
{
    //align a to 4 bytes
    if (a & 3)
    {
        a += (4 - (a & 0x3));
    }

    extern long __heap_start__;
    extern long __heap_end__;
    static char* heap_ptr = (char*)&__heap_start__;

    DBB("%d 0x%08X", a, a);
    DBB("0x%08X", heap_ptr);
    DBB("0x%08X", &__heap_start__);
    DBB("0x%08X", &__heap_end__);

    if (heap_ptr + a < (char*)&__heap_end__)
    {
        int res = (int)heap_ptr;
        heap_ptr += a;
        DBB("OK 0x%08X 0x%08X", res, heap_ptr);
        return res;
    }
    else
    {
        DBB("ERROR");
        return -1;
    }
}