0

I'm creating a stack virtual machine and wondering how vector really works underground. This question related to malloc as well.

Consider the following code:

std::vector<int> vec;
vec.push_back(1);
vec.push_back(3);
vec.push_back(7);
for (unsigned long long i = 0; i < vec.size(); i++) {
    std::cout << &vec[i] << std::endl;
}
std::cout << &vec[0] << std::endl;
std::cout << &vec[0] + 1 << std::endl;
std::cout << &vec[0] + 2 << std::endl;

with the following output in my computer:

00000292E7CF9D20
00000292E7CF9D24
00000292E7CF9D28
00000292E7CF9D20
00000292E7CF9D24
00000292E7CF9D28

The thing is; by storing all the program instructions to be run by my VM, I use a vector. I have a PC (program counter / instruction pointer):

Should the PC point to the first address of the vector and increment it by 1 each time I move to the next instruction or should I simply access it by the vector accessor (this would be slower of course...)?

Is incrementing 1 to an address a really bad practice?

I'm kinda new to the c / cpp world.

Thanks!

Erik Campobadal
  • 867
  • 9
  • 14
  • 2
    On what do you base the statement that accessing via `operator[]` is slower than what you are doing? Also there's the iterator approach to accessing vector elements. – UnholySheep Jul 12 '18 at 19:35
  • One of the benefits of std::vector is you are guaranteed contiguous memory! Although I'm not sure if I agree that the provided accessor is going to be slow. – Ben Jones Jul 12 '18 at 19:36
  • I read it here: http://prntscr.com/k5riij. Where did you see it's contiguous memory? Source of the img: http://www.craftinginterpreters.com/a-virtual-machine.html – Erik Campobadal Jul 12 '18 at 19:37
  • Yes, you can assume that. You cannot assume those addresses are stable, they *will* change when you add more elements to the vector. – Hans Passant Jul 12 '18 at 19:38
  • @ErikCampobadal That image means that, given a pointer: `T* p`, it's faster to do `*p; ++p` on each loop iteration, rather than `p[index]; ++index`. That's completely orthogonal to the use of `std::vector`. Using `vec[index]` will be just as fast as `p[index]`. However, if you use the iterator interface and write `for (auto const& value : vec) { ... }`, you'll be iterating over the vector as fast as possible (in the general case). – Justin Jul 12 '18 at 19:42
  • @Justin But in a VM, you're not always going forward, sometimes, in a jump for example, you go all the way back or forward to another location. Using an iterator would also solve this? – Erik Campobadal Jul 12 '18 at 19:44
  • 2
    @ErikCampobadal If you are jumping all over the place and want to use an index, there is no performance difference between `vec[index]` and `p[index]` where `p` is a pointer. Also note that `*(p + index)` is exactly equivalent to `p[index]`. There's no reason to avoid vector's interface unless you correctly benchmarked and *know* that there is a difference. If you do use an iterator, you could, for example, write `auto iter = vec.begin(); iter += 5; iter -= 3;`, and so forth, and it will be equivalent to pointer arithmetic – Justin Jul 12 '18 at 19:49
  • Notice how both the iterator version and the pointer version produce the exact same assembly: https://godbolt.org/g/Gb6BYc – Justin Jul 12 '18 at 19:51
  • @Justin Thanks a lot, I think that with your explanation and the duplicated thread I read clarified the answer. I'll probably try to use the vector accesor and don't think about it any more! Thanks a lot! I wish I could mark you as valid answer haha – Erik Campobadal Jul 12 '18 at 19:52

0 Answers0