【问题标题】:std::string -> execvp etcstd::string -> execvp 等
【发布时间】:2012-05-11 20:00:47
【问题描述】:

我刚刚在程序中发现了一个难以捉摸的错误,结果证明是因为启用了优化,在类似以下的情况下,有时 std::string 在 processDocument() 从中取出文本之前就被破坏了:

#include <stdio.h>
#include <spawn.h>
#include <string>
static void processDocument(const char* text) {
        const char* const argv[] = {
                "echo",
                text,
                NULL,
        };
        pid_t p;
        posix_spawnp(&p, "echo", NULL, NULL, (char**) argv, environ);
}
static int mark = 'A';
static void createDocument() {
        const char* vc;
        std::string v = "ABCKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK42";
        ++mark;
        v[0] = mark;
        vc = v.c_str();
        processDocument(vc);
}
int main() {
        createDocument();
        createDocument();
        return(0);
}

如何安全地将 std::string 转换为 char* 以用于 execvp、posix_spawnp 等?

【问题讨论】:

  • 您共享的程序不应按照您描述的方式运行。你见过那个确切的程序产生不正确的结果吗?
  • 无论是在这个程序还是您的原始程序中,您看到什么行为导致您相信“std::string 在 processDocument() 获取文本之前被破坏”?
  • >你有没有见过精确的程序产生不正确的结果?不。只要我把它修整下来,问题就神秘地消失了。 >无论是在这个程序中还是在您的原始程序中,您看到什么行为导致您相信“std::string 在 processDocument() 从中获取文本之前被破坏” 存储在 argv[1] 中的内容,从 100 开始里面的字符会乱码。
  • 原始程序可以在svn.nomike.com/playground/trunk/5D找到,调用在GUI/GTKREPL.cc中的第908行,GTKLATEXGenerator_enqueue将获取char*并用它调用外部程序。请注意,现在有一个解决方法,在该文件中搜索 /* 否则会导致内存损坏 */

标签: c++ exec


【解决方案1】:

我发现了它的真正原因(这里是实际的最小测试用例):

std::string resultString;
const char* nodeText;
const char* altText;
resultString = "......whatever1.";
nodeText = resultString.c_str();
resultString = ".....whatever2..";
altText = resultString.c_str();
printf("%s\n", nodeText); // garbage

坏主意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多