Well, you never specify what to join on in smf_topics, which means that each row in smf_messages (matching join and where criteria) will be duplicated for every row in smf_topics (matching where criteria).
You have
FROM smf_messages
INNER JOIN smf_topics
ON smf_messages.id_topic = 2
Which means that, disregarding where criteria, you will join together every row from smf_messages where id_topic is 2 with every single row in smf_topics. Taking a guess at what you want based on your query and the problem you describe, you'd want something like
FROM smf_messages
INNER JOIN smf_topics
ON smf_messages.id_topic = smf_topics.id_topic
WHERE smf_topics.id_topic = 2
First off, note that wether you state smf_topics.id_topic = 2 or sms_messages.id_topic = 2 in the where clause doesn't matter. They will both produce the same result since you are now only joining rows from messages and topics where the topic id matches. So if you also specify that either one of them has to be 2, all rows from the joined table will by extension also have to be 2.