在C语言中调用GEOS API函数出现段错误问题求助
解决libgeos C API段错误问题
你的段错误是由几个关键问题导致的,我们一步步来修复:
1. 线程安全API需配对使用
你初始化了线程安全的上下文GEOS_init_r(),但却调用了非线程安全的GEOSGeomToWKT(),这会导致上下文不匹配,引发未定义行为。必须使用对应的带_r后缀的线程安全函数。
2. 未检查关键函数的返回值
GEOSGeomFromWKT()可能因WKT格式错误、库初始化异常等返回NULL,直接对NULL使用printf("%s")会触发段错误——这正是gdb显示strlen崩溃的原因,因为printf会尝试读取无效指针的内容。
3. 未处理GEOS分配的内存
GEOS函数返回的字符串(比如转换WKT的结果)需要手动释放,否则会造成内存泄漏。
修复后的完整代码
#include <stdio.h> #include <geos_c.h> int main() { // 初始化线程安全上下文,检查是否成功 GEOSContextHandle_t ctx = GEOS_init_r(); if (ctx == NULL) { fprintf(stderr, "GEOS上下文初始化失败\n"); return 1; } // 从WKT创建几何对象,检查解析结果 const char* wkt = "MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))"; GEOSGeometry *inputGeom = GEOSGeomFromWKT_r(ctx, wkt); if (inputGeom == NULL) { fprintf(stderr, "WKT解析失败,请检查格式是否正确\n"); GEOS_finish_r(ctx); return 1; } // 使用线程安全函数转换为WKT,检查返回值 char* outputWkt = GEOSGeomToWKT_r(ctx, inputGeom); if (outputWkt != NULL) { printf("%s\n", outputWkt); GEOSFree_r(ctx, outputWkt); // 释放GEOS分配的字符串内存 } else { fprintf(stderr, "几何对象转WKT失败\n"); } // 销毁几何对象和上下文,清理资源 GEOSGeom_destroy_r(ctx, inputGeom); GEOS_finish_r(ctx); return 0; }
编译与运行
保持你的编译命令不变即可:
gcc -g -Wall geos.c -o geos -lgeos_c
关键修复点说明
- 上下文一致性:所有操作都使用带
_r后缀的线程安全函数,确保和初始化的上下文匹配。 - 空指针防护:对
GEOS_init_r()、GEOSGeomFromWKT_r()、GEOSGeomToWKT_r()的返回值都做了检查,避免对无效指针操作。 - 内存清理:用
GEOSFree_r()释放WKT字符串,用GEOSGeom_destroy_r()销毁几何对象,避免内存泄漏。
你的原始代码中,GEOSGeomToWKT()因上下文不匹配返回了NULL,导致printf("%s", NULL)触发strlen的段错误,这正是gdb显示的崩溃根源。
内容的提问来源于stack exchange,提问作者srimaln91
相关产品推荐
相关产品推荐

