realloc:没有足够的空间

时间:2012-10-08 08:12:43

标签: c++ windows memory memory-management

Windows 7,64位,MinGW工具集,代码如下:

m_data = reinterpret_cast<SampleType *>(realloc(m_data, m_size + v));  
if (NULL == m_data){  
    perror ("realloc failed");  
    exit(-1);  
}

失败并显示消息realloc failed: Not enough space
即使我多询问100个字节也会发生这种情况。而且无论我使用malloc(使用对应的指针重新分配)还是realloc。我总是这样 计算机报告超过1GB的可用内存。

以上是该方法的片段。以下是整个代码 关键是当this方法的m_data等于NULL时,此方法首次分配内存,并在cosenquent调用中将其放大。所以,请参阅下文

Wave & operator+= (const Wave wave){
    if (NULL != m_data){
        m_data = reinterpret_cast<SampleType *>(realloc(m_data, m_size + wave.DataSize()));
        if (NULL == m_data){
        perror ("realloc failed");
        exit(-1);
        }
    } else {
        m_data = reinterpret_cast<SampleType *>(malloc(wave.DataSize()));
        m_size = 0; // just for sure
    }
    /* this code fragment I used instead of realloc's one to prove that realloc is not a root of error cause
    SampleType *t_buf = reinterpret_cast<SampleType *>(malloc(m_size + wave.DataSize()));
    if (!t_buf) {perror ("malloc failed"); exit(-1);}
    memcpy (t_buf, m_data, m_size);
    free (m_data);
    m_data = t_buf;
    */
    memcpy (m_data + m_size, wave.SampleBuffer(), wave.DataSize());
    m_size += wave.DataSize();
    return *this;
};

因此,第一次使用malloc分配内存。不要怀疑。

调试器会话跟踪。

Breakpoint 2, _fu17___ZSt4cout () at ../sound_windows/Sound.h:192  
192             if (NULL != m_data){  
(gdb) print *this  
$2 = {static CHANNEL_NUMBER = <optimized out>, m_format = {wFormatTag = 1, nChannels = 2,nSamplesPerSec = 44100, nAvgBytesPerSec = 176400, nBlockAlign = 4,  
    wBitsPerSample = 16, cbSize = 18}, m_duration = 0, m_data = 0x0, m_size = 0}  
(gdb) cont  
Continuing.  

Breakpoint 2, _fu17___ZSt4cout () at ../sound_windows/Sound.h:192  
192             if (NULL != m_data){  
(gdb) print *this  
$3 = {static CHANNEL_NUMBER = <optimized out>, m_format = {wFormatTag = 1, nChannels = 2,nSamplesPerSec = 44100, nAvgBytesPerSec = 176400, nBlockAlign = 4,  
    wBitsPerSample = 16, cbSize = 18}, m_duration = 0.00451559993, m_data = 0x75d9e0, m_size = 800}  
(gdb) cont  
Continuing.  
tried to allocate 800+100 bytes  
realloc failed: Not enough space  
[Inferior 1 (process 6132) exited with code 037777777777]  

2 个答案:

答案 0 :(得分:0)

错误原因的根源是由于内存管理功能中的内存寻址混乱而发生堆栈破坏。例如,在以下代码行中

memcpy (m_data + m_size, wave.SampleBuffer(), wave.DataSize()); 

m_data + m_size表示不是它的意图,因为m_data指向两个字节大小的类型,而m_size是大小(以字节为单位)。因此,m_data + m_size会将poninter偏移到m_data的末尾,而是远离两倍的距离。

答案 1 :(得分:-1)

我怀疑现有m_data未直接与malloc分配。 realloc仅重新分配最初使用malloc分配的块。

这是因为它使用堆的内部数据结构的知识。如果块不是来自堆,如果你很幸运,你会收到一条消息,如果你运气不好,你的程序就会崩溃。

“空间不足”消息只是分配失败的一般回报。

编辑 在扩展版中,您是否在构造函数中将m_data初始化为NULL?这不会自动发生,如果你不这样做,它通常会包含一个垃圾值。

换句话说,分支if (NULL != m_data){将永远不会被命中,因为除非您初始化,否则m_data不会以NULL开头。