2013-11-30 10 views
2

У меня есть загадка, на которую у меня нет ответа. Я написал простую программу на C++ (и я должен сказать, что я не профессиональный разработчик C++). Вот оно:Valgrind - недействительный читать и писать

#include <iostream> 

int main(){ 
    const int SIZE = 1000; 
    int pool1 [SIZE]; 
    int pool2 [SIZE]; 
    int result [SIZE*SIZE]; 

    //Prepare data 
    for(int i = 0; i < SIZE; i++){ 
    pool1[i] = i + 1; 
    pool2[i] = SIZE - i; 
    } 

    //Run test 
    for(int i = 0; i < SIZE; i++){ 
    for(int j = 0; j < SIZE; j++){ 
     result[i*SIZE + j] = pool1[i]*pool2[j]; 
    } 
    } 

    return 0; 
} 

Программа, кажется, работает (я использую его в качестве своего рода эталоном для разных языков), но потом я побежал с Valgrind и он начал complaing:

==25912== Invalid read of size 4 
==25912== at 0x804864B: main (in /home/renra/Dev/Benchmarks/array_iteration/array_iteration_cpp) 
==25912== Address 0xbee79da0 is on thread 1's stack 

==25912== Invalid write of size 4 
==25912== at 0x8048632: main (in /home/renra/Dev/Benchmarks/array_iteration/array_iteration_cpp) 
==25912== Address 0xbeaa9498 is on thread 1's stack 

==25912== More than 10000000 total errors detected. I'm not reporting any more. 
==25912== Final error counts will be inaccurate. Go fix your program! 

Хм, не выглядит хорошо. Размер 4, вероятно, относится к размеру int. Как вы можете видеть, сначала я использовал SIZE 1000, поэтому массив результатов составлял бы 1 000 000 целых чисел. Итак, я подумал, что это просто переполнение, и мне нужен более крупный тип значения (по крайней мере, для итераторов и массив результатов). Я использовал unsigned long long (максимальная длина без знака - 18 446 744 073 709 551 615, и все, что мне нужно, было 1,000,000 - SIZE * SIZE). Но я все еще получаю эти сообщения об ошибках (и они все еще говорят, что размер чтения и записи равен 4, хотя sizeof (long long) равен 8).

Также сообщений нет, когда я использую более низкий РАЗМЕР, но они, похоже, срабатывают точно в РАЗМЕР 707 независимо от используемого типа. Кто-нибудь знает? Мне очень любопытно :-).

+5

Вы должны использовать valgrind с вашей программой, скомпилированной в режиме отладки, чтобы получить точный номер строки ошибок. – HAL9000

+7

Элемент массива '1000000' в стеке - это плохая идея, не делайте этого. –

+0

У вас, ребята, какое-то эмпирическое правило о том, сколько данных по-прежнему хорошо держать в стеке, и когда это уже слишком много? – Renra

ответ

3

C и C++ у обоих нет четкого ограничения на размеры массивов, которые вы сможете использовать в стеке, а также, как правило, не встроенная защита. Просто не выделяйте такие большие куски как автоматические (область локальных) переменных. Используйте malloc в C или new в C++ для такой цели.

+0

Спасибо. Я выделил массив результатов в куче, и valgrind счастлив. – Renra

Смежные вопросы