GDAL代码崩溃:OGRFieldDefn修改指针致地址异常求助
问题分析与解决
你的问题是典型的编译链接环境ABI不兼容导致的内存损坏——实例化OGRFieldDefn时改写了其他变量的内存空间,本质是程序与GDAL库的内存管理规则不统一。
核心原因及解决办法
1. 强制保持CRT环境一致性
你使用的是MSYS2 UCRT64仓库的GDAL,必须在UCRT64的shell环境下编译代码,不能混用MSYS2的其他环境(如mingw64、clang64)。不同环境的C运行时库(CRT)不兼容,跨环境编译链接会导致内存分配/释放时的地址混乱。
2. 使用正确的编译链接参数
编译时必须借助GDAL提供的配置工具生成编译选项,避免手动指定路径出错。编译命令应写为:
g++ your_code.cpp -o point_out.exe $(gdal-config --cflags --libs)
gdal-config --cflags会自动添加头文件路径、宏定义等编译参数,--libs会自动添加库路径和链接的库文件,确保程序与GDAL库的编译参数完全匹配。
3. 修正代码中的不规范问题
你的代码使用cout但未包含<iostream>头文件,虽不是直接引发指针篡改的原因,但会导致未定义行为,需补上:
#include "ogrsf_frmts.h" #include <iostream> // 必须包含该头文件 int main() { GDALAllRegister(); GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName("ESRI Shapefile"); GDALDataset *poDS; poDS = poDriver->Create( "point_out.shp", 0, 0, 0, GDT_Unknown, NULL ); OGRLayer *poLayer; poLayer = poDS->CreateLayer( "point_out", NULL, wkbPoint, NULL ); std::cout << "Pointers before call: " << poDS << " " << poLayer << std::endl; OGRFieldDefn oField( "Name", OFTString ); oField.SetWidth(32); std::cout << "Pointers after call: " << poDS << " " << poLayer << std::endl; GDALClose( poDS ); return 0; }
4. 尝试替换GDAL版本或分发渠道
如果当前3.9.3版本仍有问题,可尝试MSYS2 UCRT64仓库里的GDAL 3.8.x旧版本,用pacman安装:
pacman -S mingw-w64-ucrt-x86_64-gdal=3.8.4-1
另外,OSGeo4W提供的MinGW版本GDAL针对GIS开发做了更严格的兼容性测试,也可尝试用该环境编译运行。
结论
这大概率不是GDAL的Bug,而是你的编译链接环境与GDAL库环境不匹配导致的内存冲突。按上述步骤调整环境和编译参数,即可解决指针被篡改的问题。
内容的提问来源于stack exchange,提问作者Cornelia
相关产品推荐
相关产品推荐

