Противоположный результат направления стека в C с использованием valgrind - PullRequest
0 голосов
/ 16 ноября 2011

Я использую valgrind, чтобы выяснить запутанную проблему направления стека.

См. Код ниже, я хочу знать, почему оператор "p1 + = 0x80; * p1 = 1" действителен иоператор "p2 - = 0x80; * p2 = 1" является недопустимой записью в соответствии с valgrind?

Я думаю, что все переменные распределены в стеке в соответствии с ОС, и она растет доболее низкий адрес, поэтому я думаю, что «- =» является действительным, а «+ =» недопустимым, потому что он может быть большим по сравнению с вершиной стека, которая может быть не в пределах стека.

#include <stdlib.h>

int main()
{
    int a;
    int *p1 = &a;
    p1 += 0x80;
    int *p2 = &a;
    *p1 = 1;
    p2 -= 0x80;
    *p2 = 1;
    return EXIT_SUCCESS;
}

Ответы [ 3 ]

7 голосов
/ 16 ноября 2011

Нет, этот код дает неопределенное поведение.

Ваш стек состоит из целого числа и целочисленного указателя и ничего более.

Когда вы перемещаете указатель на 0x80 дюймов вперед в памяти (мимо стека)и напишите там, что вы вызвали неопределенное поведение, вы не можете поверить в то, что произойдет после этого.

Конечно, правильно перемещать указатель туда, вы можете перемещать его куда угодно, но не писать там.

0 голосов
/ 17 ноября 2011

Когда вы добавляете 0x80 к p1, вы получаете указатель, который указывает где-то ранее в кадре стека - вероятно, где хранятся аргументы main() или среда.Вот почему Valgrind не предупреждает вас - он не знает, что вы не делаете правильный доступ к этой части стека.

Когда вы вычитаете 0x80 из p2, вы заканчиваетевверх с указателем, который указывает ниже %esp.Эта часть стека логически еще не выделена, поэтому Valgrind предупреждает вас.

0 голосов
/ 16 ноября 2011

Сначала вы дали нам код, который даже не компилируется.

Тогда, проход 128 позиций за объектом - неопределенное поведение, идете ли вы за объектом или впереди. В вашем примере ваш -= 0x80 должен вернуть вас к исходному указателю.

Таким образом, valgrind, вероятно, будет в порядке со вторым, даже если ваше первое назначение *p, возможно, уже разбило ваш стек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...