Concat中的两个字符串并分配动态缓冲区

时间:2014-06-17 12:21:36

标签: c++ string memory-management

我知道这个问题已经被问到了。我还使用this topic的解决方案进行测试。但是,我想知道如何使用这种函数而没有内存泄漏也不例外。

注意: LPTSTRchar*LPCTSTRconst char*

void add_to_buffer(LPTSTR* buffer, LPCTSTR msg) {
    // Determine new size
    int newSize = 0;

    // Allocate new buffer
    if (*buffer == NULL)
        newSize =  _tcsclen(msg) + 1; // strlen()
    else
        newSize = _tcslen(*buffer) + _tcsclen(msg) + 1;

    LPTSTR newBuffer = (LPTSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newSize); // malloc()

    // Do the copy and concat
    if (*buffer == NULL)
        _tcscpy(newBuffer, msg); // strcpy()
    else
    {
        _tcscpy(newBuffer, *buffer);
        _tcscat(newBuffer, msg); // strcat()
        // release old buffer
        HeapFree(GetProcessHeap(), 0, *buffer); // free()
    }

    // store new pointer
    *buffer = newBuffer;
}

试验:

LPTSTR test = NULL;
add_to_buffer(&test, _T("User:\r\n"));
add_to_buffer(&test, _T("42"));

首先致电add_to_buffer。但是,第二个函数调用会导致HeapFree处的异常。我确定这是关于指针的问题,但我不明白如何解决它。

这是一个好方法吗?如何解决我的异常?

2 个答案:

答案 0 :(得分:0)

如果您的程序启用了unicode,则表示您没有分配足够的内存 - 因为字符串长度(符号)和字符串大小(字节)不匹配。

如果不是,我没有看到使用非标准C类型而非标准类型的原因。但这应该不是问题。

答案 1 :(得分:0)

如果您将代码编译为多字节应用程序

LPTSTR newBuffer = (LPTSTR)HeapAlloc(
  GetProcessHeap(), 
  HEAP_ZERO_MEMORY, 
  newSize
); 

可能会分配给很少的内存。

要解决此问题:

LPTSTR newBuffer = (LPTSTR)HeapAlloc(
  GetProcessHeap(), 
  HEAP_ZERO_MEMORY, 
  newSize * sizeof(*newBuffer)
); 

除此之外,代码缺少对系统调用的错误检查,代码看起来很好。

但是,为了简化操作,可以使用HeapReAlloc()代替HeapAlloc()HeapFree()的组合。

如果程序崩溃了,这可能是因为在您发现实际崩溃之前内存管理已经被混淆了。