2015-10-04 2 views
0

У меня есть следующий код для добавления строки в другую в цикле.Ошибка в выходе после цикла вызвана strcat?

Код

#include<stdio.h> 
#include<string.h> 

int main(void){ 
     char src1[] = "name"; 
     int i; 
     for (i=1;i<=5;i++){ 
       strcat(src1,"opps"); 
       printf("loop times %d\n",i); 
     } 
       printf("now src1 is:%s\n",src1); 
     return 0; 
} 

Для отладки кода, я добавил printf заявления в коде и скомпилирован. Когда я бегу, я получаю следующий результат:

Выход

раз цикл 1 раз цикл 0 раз петля 1886416641 Теперь src1 является: nameoppsoppsopps

Мой вопрос: «Почему printf цикл 1886416641 раз? " Кроме того, результат также не то, что я ожидал. Может ли кто-нибудь прояснить это для меня?

+0

Вы пишите из границ. В этом случае вы перезаписываете счетчик циклов. – EOF

+0

Вместо «результата тоже не то, что я ожидал», более полезно опубликовать то, что ожидалось. – chux

ответ

3

Существует только 5 байтов, выделенных для str1, а strcat будет получать доступ за пределы, то это может привести к неопределенному поведению.

Номер 1886416641 был просто случайно получен.

Чтобы получить нормальный результат, вам необходимо выделить достаточно памяти до str1.
пример: char src1[32] = "name";

+2

'1886416641' * почти * случайно: это' 0x70706F01', поэтому ascii 'ppo '\ 1''. Это означает, что вы, возможно, узнаете от него спецификацию машины OP. – EOF

+0

спасибо, я расширил пространство памяти до S1, теперь он работает. –

3

Ваш src1[] не достаточно большой. Когда вы добавляете второй «opps», он перезаписывает i. Значение 1886416641 равно hex 70706f01: 0x70 = 'p', 0x70 = 'p', 0x6f = 'o'.

Компилятор округляется до следующего 32-битного машинного слова. Стек в байтах выглядит следующим образом:

start:  loop1 loop2 
src1[]: 
    n 
    a 
    m 
    e 
    \0  o 
    <fill> p 
    <fill> p 
    <fill> s 
i: 
    00  \0 o 
    00  00 p 
    00  00 p 
    01  02 s 
        \0 

(стек не точны, а некоторые элементы на самом деле обратное - использовать его в качестве примера)

+0

Чтобы быть понятным «Когда вы добавляете второй« opps », он перезаписывает i» - это пример неопределенного поведения, вызванного 'srtrcat()', написанным за пределами 'src1 []'. Это объясняет результаты OP - которые могут отличаться в другой день/платформу и т. Д. – chux

1

Просто, чтобы добавить немного деталей к уже существующим ответы, в соответствии с man page из strcat(),

char *strcat(char *dest, const char *src);

strcat() функция добавляет src строку к dest, перезаписывая завершающий нулевой байт ('\ 0') в конце dest, а затем добавляет завершающий нулевой байт. Строки могут не перекрываться **, а строка dest должна иметь достаточно места для результата. Если dest недостаточно велико, поведение программы непредсказуемо; [...]

В случае, если ваша окончательная строка иметь больше длины, чем места назначения может хранить, вы будете получать доступ из связанной памяти, которая вызывает undefined behavior.

В вашем коде src1 получает свой размер от длины строки инициализатора.На более позднем этапе, если вы хотите сохранить одну длительную, вам нужно выделить больше памяти в самом начале, как

char src1[128] = "name"; 

или подобное.

Смежные вопросы