I think you just have the wrong expectations. Let's work with simple ints:
Code:
#include <iostream>

void setInt(int* p) {
	*p = 1;
}

int main() {
	int* p = new int;
	*p = 0;
	std::cout << "Value before setInt() call: " << *p << std::endl;
	setInt(p);
	std::cout << "Value after setInt() call: " << *p << std::endl;
	delete p;
	std::cin.get();
	return 0;
}
The expected output is:
Code:
Value before setInt() call: 0
Value after setInt() call: 1
Here p is the pointer, *p is the data that is pointed to. It is clear that the *p = 1 in setInt() means "change the data pointed to by p to 1". So the data pointed to is changed to 1. As simple as that.

For your example, tp->data = 1 is a shorthand for (*tp).data, after which the same reasoning applies: change the data member of the struct pointed to by tp to 1.

It could be that you have the local scope of setframe() and setInt() in mind. The thing is, working with the pointer means that we're working with memory, which isnt limited by function scope.