2016-11-04 10 views
1

Код:Что такое разбивка стека (C)?

int str_join(char *a, const char *b) { 
    int sz =0; 
    while(*a++) sz++; 
    char *st = a -1, c; 
    *st = (char) 32; 
    while((c = *b++)) *++st = c; 
    *++st = 0; 
    return sz; 
} 

.... 

char a[] = "StringA"; 
printf("string-1 length = %d, String a = %s\n", str_join(&a[0],"StringB"), a); 

Выход:

строка-1 длина = 7, символ * а = StringA StringB

*** стек разбивая обнаружено ****:/Т02 прекращается

Прервано (ядро сбрасывали)

Я не понимаю, почему он показывает стек разбив? и что такое разбитие стека? Или это ошибка моего компилятора?

+1

Возможный дубликат [обнаружение разбитого стека] (http://stackoverflow.com/questions/1345670/stack-smashing-detected) – piyushj

ответ

4

Ну стеков разбив или стек переполнения буфера довольно подробная тема будет обсуждаться здесь, вы можете обратиться к this wiki article для получения дополнительной информации.

Приведенный здесь код, проблема в том, что ваш массив a не достаточно велик, чтобы провести окончательный конкатенированный результат.

Таким образом, говоря

while((c = *b++)) *++st = c; 

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

Чтобы решить эту проблему, вам необходимо убедиться, что массив a содержит достаточно места для хранения как первой, так и второй строки , объединенных вместе. Короче говоря, вы должны предоставить более крупный целевой массив.

+0

любое решение для этого? – Gonzalez

+0

@ Гонсалес для чего? Вы пропустили последний абзац в своем ответе? –

+0

Да, я не видел его первым. – Gonzalez

0

Разрушение стека означает, что вы написали вне («разбитое» прошлое/пространство) пространство для хранения функций для локальных переменных (эта область называется «стеком», в большинстве систем и языков программирования). Вы также можете найти этот тип ошибок, называемый «переполнение стека» и/или «стековый поток».

В вашем коде C, вероятно, помещает строку, указанную a в стек. В вашем случае место, которое вызывает разбиение стека, - это когда вы увеличиваете st за исходным указателем a и записываете туда, где он указывает, вы пишете вне области, компилятор C гарантирует, что зарезервировано для исходной строки, назначенной в a ,

Всякий раз, когда вы пишете за пределами области памяти, которая уже должным образом «зарезервирована» на C, это «неопределенное поведение» (что означает, что язык C/стандарт C не говорит, что происходит): обычно вы оказываетесь перезаписывая что-то еще в памяти вашей программы (программы обычно помещают другую информацию рядом с вашими переменными в стеке, такие как обратные адреса и другие внутренние детали), или ваша программа пытается писать за пределами памяти, которую операционная система «разрешила» использовать , В любом случае программа обычно ломается, иногда сразу и явно (например, с ошибкой «ошибка сегментации»), иногда очень скрытыми способами, которые не становятся очевидными до конца позже.

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

Решение сводится к необходимости явно указывать вашему коду достаточную память для вашей комбинированной строки. Вы можете сделать это, явно указав длину массива «a», чтобы быть достаточно длинным для обеих строк, но этого обычно достаточно для простого использования, когда вы заранее знаете, сколько места вам нужно. Для решения общего назначения вы должны использовать такую ​​функцию, как malloc, чтобы получить указатель на новый кусок памяти из операционной системы, размер которого вам нужен/нужен, как только вы вычислите, какой будет полный размер (просто не забудьте позвонить free по указателям, которые вы получаете от malloc и аналогичные функции, как только вы закончите с ними).

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

  • Нет связанных вопросов^_^