Just a couple things for clarification, you're using three different terms in your post, and each has a different meaning. Your title says you are looking for "unique host id of machine," your first sentence asks for the "physical address of ethernet card," and then you say it's possible that ifconfig can return the wrong "mac address."
I assume what you want is the MAC address of the ethernet card, because that's what you spend most of the time talking about. This isn't a lecture, but be aware that the "physical address" of a device typically refers the the address in memory where a memory-mapped device can be accessed, and a "unique host id" probably causes people to think you're looking for processor serial numbers or the like.
First thing, I haven't messed with it, but if I recall, VirtualBox allows the user to specify a MAC address for any virtual network adapter added to the virtual machine. I think the MAC address is randomly selected for each NIC created (but I'm not 100% certain of that). The MAC address is under the "advanced" section of each adapters configuration if you're using the VirtualBox GUI. If you're not using the VirtualBox GUI, I imagine the MAC address is modified with modifyvm, etc.
The reason I mention all that is because, if you're running a C/C++ program on a virtual machine, I don't think it's even possible
for you to retrieve the "real" or host machine's MAC address. Your C/C++ program's universe will be the guest machine--unless you do some special networking configuration.
With all that said, I'll give you two alternatives to ifconfig. The first is much, much better than the second. Though, the first may be source for what ifconfig reads.
1. Read the address from the /sys filesystem. For example, on my system:
$ cat /sys/class/net/eth0/address
$ cat /sys/class/net/eth1/address
2. Look at dmesg output. For example, on my system:
$ dmesg | grep eth0
[ 1.854863] eth0: RTL8110s at 0xffffc9000067ec00, 00:22:fb:c3:3f:0b, XID 04000000 IRQ 21
[ 13.241043] udev: renamed network interface eth0 to eth1
[ 13.291075] udev: renamed network interface eth1_rename to eth0
[ 16.314517] r8169: eth0: link up
[ 16.314526] r8169: eth0: link up
[ 26.560873] eth0: no IPv6 routers present
The MAC address of the NIC is displayed on the first line of the output. Keep in mind though, the output shows that udev rules might swap device names. In this case, eth0 got moved to eth1. Your program would need to check for such a rename, and then check if that new name was later renamed, and so on.
The only other option I could think of would be to try and read the MAC address directly from the NIC itself. The would mean accessing device registers through memory--device registers that can vary between different devices.