У вас происходит несколько вещей. Некоторые из приведенных выше комментариев помогают, но давайте рассмотрим их.
Во-первых, если вы используете C ++ и держите строки, вы должны использовать std :: string. Тем не менее, ваша проблема говорит о том, что вы только учитесь, поэтому давайте придерживаться старой школы C.
Вы выделили двумерный массив из отдельных символов. Таким образом, вы храните всего 12 символов данных.
В C (или C ++) строки заканчиваются нулем. То есть, если вы храните в виде строки «Привет», это на самом деле 3 символа, а не два. H, I и нулевой байт, обозначающий конец строки.
strlen просто считает количество символов до нулевого байта. Так что в моем примере 2.
У вас нет 0-байтов в вашем массиве, поэтому strlen считает до тех пор, пока не достигнет нуля по какой-то другой причине - полностью за пределами вашего массива. Хлоп!
Итак ... При работе с одиночными символами ошибочно использовать строковые методы (strlen, strdup и т. Д.).
Теперь самым безопасным будет использовать вектор std :: string, как предлагали другие. Тем не менее, я твердо верю в понимание основ до принятия ярлыков, и это ярлык.
Так что если вам действительно нужны 3 строки, но вы хотите использовать old-school C, то у вас должен быть на самом деле одномерный массив char *.
char *m[3];
m[0] = "Hello";
m[1] = "there";
m[2] = "everyone";
Было бы ДЕЙСТВИТЕЛЬНО странно хранить строки так, как вы это делаете, и считается довольно опасным использовать буферы символов фиксированной длины для хранения строк. Вот откуда взялись печально известные эксплойты переполнения буфера, наиболее распространенные эксплойты в старых школьных веб-приложениях.
Кроме того, вы можете изменить свой пример. сделайте m [3] [5] и сохраняйте нулевой байт в каждой строке после конца ваших строк. strlen () начнет работать. Но это действительно некрасиво.