需要使用C API通过Clang发布资源
Need to release resources with Clang using C API?
很抱歉有一个很傻的问题:当使用Clang C API函数时,我应该释放命令args-vars和未保存的文件结构吗?我知道在常见情况下应该释放资源以避免内存泄漏,但我想知道Clang是否在clang_disposeTranslationUnit()
上自己这样做。
在parse/diags+tokenize/desole的几次迭代之后,我遇到了clang崩溃,所以我必须逐一消除可能的问题。
解析示例:
char **args;
CXUnsavedFile *files;
// allocate args
args = new char*[N];
for (int i=0; i<N; i++) {
int len = strlen(argv[i]);
args[i] = new char[len + 1];
args[i][len] = 0;
strcpy(arg[i], argv[i]);
}
// allocate unsaved files
files = new CXUnsavedFile[M];
for (int i=0; i<M; i++) {
files[i].Filename = new char[BBB]; // + fill Filename
files[i].Contents = new char[CCC]; // + fill Contents
files[i].Length = strlen(files[i].Contents);
}
clang_parseTranslationUnit(..., args, N, files, M);
// release resources (need to do?)
// args
for (int i=0; i<N; i++) {
delete []args[i];
}
delete[] args;
// unsaved files
for (int i=0; i<M; i++) {
delete []files[i].Filename;
delete []files[i].Contents;
}
delete []files;
最新消息:对于那些认为这真的很愚蠢的人来说,30秒内回答崩溃的原因是什么:
12-11 00:10:38.126: INFO/DEBUG(166): backtrace:
12-11 00:10:38.126: INFO/DEBUG(166): #00 pc 0001832a /system/lib/libc.so
12-11 00:10:38.126: INFO/DEBUG(166): #01 pc 0000dc04 /system/lib/libc.so (abort+4)
12-11 00:10:38.126: INFO/DEBUG(166): #02 pc 0001f0df /system/lib/libc.so (__assert2+30)
12-11 00:10:38.126: INFO/DEBUG(166): #03 pc 0077c954 /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::Lexer::getSourceLocation(char const*, unsigned int) const+76)
12-11 00:10:38.126: INFO/DEBUG(166): #04 pc 0077ca4c /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::Lexer::FormTokenWithChars(clang::Token&, char const*, clang::tok::TokenKind)+100)
12-11 00:10:38.126: INFO/DEBUG(166): #05 pc 00781098 /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::Lexer::LexTokenInternal(clang::Token&)+5616)
12-11 00:10:38.126: INFO/DEBUG(166): #06 pc 0015de68 /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::Lexer::LexFromRawLexer(clang::Token&)+116)
12-11 00:10:38.126: INFO/DEBUG(166): #07 pc 00781d3c /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::Lexer::getRawToken(clang::SourceLocation, clang::Token&, clang::SourceManager const&, clang::LangOptions const&)+220)
12-11 00:10:38.126: INFO/DEBUG(166): #08 pc 00781d9c /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::Lexer::MeasureTokenLength(clang::SourceLocation, clang::SourceManager const&, clang::LangOptions const&)+36)
12-11 00:10:38.126: INFO/DEBUG(166): #09 pc 001d1824 /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::DiagnosticRenderer::emitMacroExpansions(clang::SourceLocation, clang::DiagnosticsEngine::Level, llvm::ArrayRef<clang::CharSourceRange>, llvm::ArrayRef<clang::FixItHint>, clang::SourceManager const&, unsigned int&, unsigned int)+840)
12-11 00:10:38.126: INFO/DEBUG(166): #10 pc 001d13ec /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::DiagnosticRenderer::emitDiagnostic(clang::SourceLocation, clang::DiagnosticsEngine::Level, llvm::StringRef, llvm::ArrayRef<clang::CharSourceRange>, llvm::ArrayRef<clang::FixItHint>, clang::SourceManager const*, llvm::PointerUnion<clang::Diagnostic const*, clang::StoredDiagnostic const*>)+1224)
12-11 00:10:38.126: INFO/DEBUG(166): #11 pc 001d1b20 /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::DiagnosticRenderer::emitStoredDiagnostic(clang::StoredDiagnostic&)+304)
12-11 00:10:38.126: INFO/DEBUG(166): #12 pc 0017b1c8 /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang.so (clang::cxdiag::lazyCreateDiags(CXTranslationUnitImpl*, bool)+248)
12-11 00:10:38.126: INFO/DEBUG(166): #13 pc 00009028 /data/data/name.antonsmirnov.android.arduinodroid/lib/libclang_wrapper.so (Java_name_antonsmirnov_clang_clang_1wrapper_getDiagnostics+72)
12-11 00:10:38.126: INFO/DEBUG(166): #14 pc 0001fb70 /system/lib/libdvm.so (dvmPlatformInvoke+112)
12-11 00:10:38.126: INFO/DEBUG(166): #15 pc 0004e8b9 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+360)
12-11 00:10:38.126: INFO/DEBUG(166): #16 pc 00029020 /system/lib/libdvm.so
12-11 00:10:38.126: INFO/DEBUG(166): #17 pc 0002d7e8 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
12-11 00:10:38.126: INFO/DEBUG(166): #18 pc 0005fed5 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+272)
12-11 00:10:38.126: INFO/DEBUG(166): #19 pc 0005feff /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
12-11 00:10:38.126: INFO/DEBUG(166): #20 pc 00055327 /system/lib/libdvm.so
12-11 00:10:38.126: INFO/DEBUG(166): #21 pc 00012e70 /system/lib/libc.so (__thread_entry+48)
12-11 00:10:38.126: INFO/DEBUG(166): #22 pc 000125c8 /system/lib/libc.so (pthread_create+172)
管理动态内存最可靠的方法是使用为此设计的类:
std::vector<char const *> args(argv, argv+N); // replaces first loop
std::vector<CXUnsavedFile> files(M);
// Same loop to set up files
for (int i=0; i<M; i++) {
files[i].Filename = "test_file.cpp";
files[i].Contents = "int a = 10;";
files[i].Length = strlen(files[i].Contents);
}
clang_parseTranslationUnit(..., args.data(), args.size(), files.data(), files.size());
// no need to delete anything.
如果你真的想通过为了教育目的而篡改指针来管理内存,那么我可以发现以下错误:
args = new char*[N]; // not '*args' - args doesn't point to anything yet
files = new CXUnsavedFile[M] // not 'new CXUnsavedFile()' - you want an array
不要删除files[i].Filename
或files[i].Contents
,因为您没有new
。它们指向具有静态生存期的字符串文字,这意味着它们在程序结束时会自动销毁。
是的,必须释放用new分配的资源。我崩溃是因为并发问题——同一文件的并发解析(clang_parseTranslationUnit
)和索引(clang_indexSourceFile()
)。谢谢迈克。
相关文章:
- 具有瞬态资源的RAII类
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 允许从 std::map 的密钥窃取资源?
- 参考资源文件VC++中的$(SolutionDir)
- 如何维护资源管理器项目视图中当前可见的项目列表
- 将 std::allocate_shared 与多态资源分配器一起使用
- 使用RAII在给定次数的迭代后重新分配资源
- 资源管理设计模式
- 如何跨平台将二进制资源构建到程序中?
- SetDlgItemInt 不会更改嵌入资源的编辑框
- Klocwork Inside的资源泄漏
- 从存储为 Windows 资源 (c++) 的 png 中获取 png 文件数据
- C++链接时间资源"allocation"而不定义
- 使用 Bazel 生成 QT 资源文件
- 编译器资源管理器和 GCC 具有不同的输出
- 使用 Bazel 编译 QT 应用程序时访问资源
- 根据需要声明资源,而不重复它们
- meson-build:wxWidgets 资源文件,用于 Windows 未构建
- Windows 资源管理器中的图标在使用 resource.rc 时显示 2 个不同的图标
- C++ 返回异常,我应该释放资源吗?