Valgrind 抱怨通过指向结构的指针访问结构成员时读取无效



结构定义如下:

struct section_{
    int start;
    ...
};

出于我不会讨论的原因,我需要将指向结构的指针传递给接受void*的函数。该函数如下所示:

void* my_fun(void* sec){
    section_* section = (section_*)sec;
    int start = section->start; // <---- valgrind complains here
    ...
}

我有一个std::vector<section_*>,我需要在这个向量的每个元素上调用my_fun。我是这样做的:

std::vector<section_*> sections = get_sections();
for (int i = 0; i < sections.size(); ++i){
    my_fun((void*)sections[i]);
}

get_sections()函数如下所示:

std::vector<section_*> get_sections(){
    std::vector<section_*> sections;
    section_ sec1;
    sec1.start = 0;
    ...
    sections.push_back(&sec1);
    return sections;
}

我已经将问题追踪到my_fun中的行,上面写

int start = section->start;

错误说:

==3512== Invalid read of size 4
==3512==    at 0x41A970: my_fun(void*)
...
==3512==  Address 0xffeffa2a0 is on thread 1's stack
==3512==  14160 bytes below stack pointer

即使我得到无效的读取,我仍然能够访问my_fun结构的成员,并且它们是正确的值。为什么?

意识到这段代码是零碎的,但实际代码比我展示的代码要复杂和冗长得多,尽管我认为我正在展示所有相关部分。我希望我提供的信息就足够了。

如 @BoPersson 的注释中所述,您将一个局部变量添加到向量中:

std::vector<section_*> get_sections(){
    std::vector<section_*> sections;
    section_ sec1;    // <- Local, temporary variable 
    sec1.start = 0;
    ...
    sections.push_back(&sec1); // <- Address of local var
    return sections;
    // When this function ends, sec1 is no longer valid
}

您可以使用new创建sec1(稍后delete创建)。或者将矢量类型更改为 std::vector<section_> sections;

最新更新