c++ - 如何正确使用 LocalAlloc 和 LocalReAlloc
问题描述
我将学习如何使用LocalAlloc
以及LocalReAlloc
Win32 API。我编写了以下代码,但它给了我例外。我不知道下面的代码有什么问题。
#include <Windows.h>
#include <iostream>
namespace code
{
namespace memory
{
void allocation()
{
char* string = reinterpret_cast<char*>(LocalAlloc(LPTR, 6 + 1));
CopyMemory(string, "WINAPI", 6);
std::printf("%s\n", string);
string = reinterpret_cast<char*>(LocalReAlloc(string, 6 + 13 + 1, LMEM_MOVEABLE));
CopyMemory(string + 6, "IS THE BEST", 13);
std::printf("%s\n", string);
delete string;
}
}
}
int main(int argc, char* argv[])
{
code::memory::allocation();
return 0;
}
当我编译上面的程序时,它没有给我任何错误,但是当我运行它时,它给了我异常。以下消息来自异常:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...Windows\00 Windows API Programming\Debug\52_DynamicMemory.exe
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 904
Expression: _CrtIsValidHeapPointer(block)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
解决方案
您的代码有几个问题。
完全缺乏错误处理。
如果LocalReAlloc()
失败,您将泄漏由LocalAlloc()
.
第二个CopyMemory()
是超出了被复制的字符串文字的范围。printf()
如果文字被正确复制,您并不能确保为以下内容重新分配的内存为空终止。
您没有正确释放分配的内存。你必须使用LocalFree()
,而不是delete
。
试试这个:
#include <Windows.h>
#include <cstdio>
#include <cstring>
namespace code
{
namespace memory
{
void allocation()
{
char* string = static_cast<char*>(LocalAlloc(LMEM_FIXED, 6 + 1));
if (!string) return;
std::strcpy(string, "WINAPI");
std::printf("%s\n", string);
char* newstring = static_cast<char*>(LocalReAlloc(string, 6 + 12 + 1, LMEM_MOVABLE));
if (!newstring) { LocalFree(string); return; }
string = newstring;
std::strcpy(string + 6, " IS THE BEST");
std::printf("%s\n", string);
LocalFree(string);
}
}
}
int main()
{
code::memory::allocation();
return 0;
}
推荐阅读
- java - Spring Boot 不断询问登录凭据
- php - 在vuejs上上传文件时获取“未定义的偏移量:1” - php
- python - 如何检查一个列表是否是另一个列表的子集(有容差)
- sql - PL/SQL 从 Oracle 包中读取定义的游标,返回 SYS_REFCURSOR,使用 cx_Oracle
- javascript - celery 任务总是在 Node 中返回 null
- javascript - $Emit 传递“未定义”属性而不是 int 属性?
- html - 在页面中心并排对齐 3 个图像?HTML
- javascript - 将 drawio HTML 嵌入到 React 中
- vhdl - VHDL 代码错误:接近文本 e_my.vhd(61)"my_7segdec";期待“;”,或“端口”,或“通用”
- google-picker - Google Drive Picker API 和设置范围以避免登录错误