There's no concept of DDOS in contracts in the same vein as a web server in Ethereum. You can send as many transactions as you want, but you won't be able to block access to it, simply by flooding it with transactions. To DDOS, you would have to try and DDOS the whole Ethereum network. In this attack, you essentially send so many transactions that you fill up the gas limit in each block, such that people who pay normal fees for gas, won't get their transactions included until later blocks. The gas limit would increase per each block (due to Ethereum's dynamic block sizes) and thus the attack would become increasingly costly over time. This is generally, an expensive attack to maintain as you would have to pay for all the gas each time. At 50 shannon per gas & 2usd/ether, it would amount to about $1600 per day to keep blocks filled up at current rate (3.14 million gas per block * 50 shannon = 0.157 ether * ~5083 blocks per day * ~2$/ether). (Correct me if my calculations are wrong).
There are other attacks one could do on contracts if it is not coded correctly. You are correct at inferring that if a contract loops through addresses and you could just add new ones, then at some point, the contract won't be able to execute a transaction within the current gas limit. Which would block access.
Another attack is to create a parasitic contract that drains all the gas automatically, rendering service unusable for other participants. For example, if you use address.call.value (and not send() in Solidity) to send funds to another contract/address, then you could maliciously just drain all gas. For example, let's say you want to send dividends to participants. The 3rd person down the line, put in this attack, draining all the gas, thus not allowing any other people to receive any dividends.
There are other attacks as well such as the call stack attack, where you basically fill up the stack BEFORE issuing a call to another contract. This could be damaging if not properly checked/accounted for. See more here: http://martin.swende.se/blog/Devcon1-and-contract-security.html
So, yes, there are ways to make current contracts unusable IF the smart contract developer did not know about these potential attacks. Solidity has some checks in place to protect against some of this (use send() when possible for example), but not all possibilities are mitigated.
sendTransaction
call and then can scale to attack from many nodes from VMs/containers.