2016-05-31 2 views
1

структура определяется как таковую: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, и они являются правильными значениями. Почему это?

Я понимаю, что этот код в маленьких кусочков, но фактический код является гораздо более сложным и длительным, чем я показываю, хотя я думаю, что я показываю все соответствующие части. Я надеюсь, что информация, которую я дал, достаточно.

+0

пытались ли вы с помощью [static_casting] (http://www.cplusplus.com/doc/tutorial/typecasting/), это выглядит как проблема литья. – Vtik

+0

@ Vtik Я никогда раньше не использовал это ... Я буду смотреть на это. Благодаря – asrjarratt

+1

Это 'sections.push_back (&sec1); возвратные секции;.' Возвращает указатель на локальную переменную, как говорится в сообщении * == 3512 == Адрес 0xffeffa2a0 на поток 1 в стек * –

ответ

2

Как уже упоминалось в комментариях @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;.

+0

Кроме того, почему я в состоянии получить доступ к членам структуры (дающие правильные значения), если' sec1' уже не действует – asrjarratt

+0

Хорошо, что имеет смысл, так.?. , если изменить тип вектора для STD :: вектор секции, я могу передать и секции [я] к my_fun, да? – asrjarratt

+1

Вы просто повезло получить. [Этот ответ] (http://stackoverflow.com/a/6445794/669576) может помочь. –