2012-03-31 2 views
1

У меня есть такой код, который решается мной следующая проблема упражнений из K & R книги:Как преодолеть ошибку Stack Smashing?

#include<stdio.h> 
void stringCat(char *s,char *t) 
{ 
    while(*s++); 
    while((*s++ = *t++)); 
} 
void main() 
{ 
    char message1[] = "hello whats been up?"; 
    int i; 
    char message2[] = "this should be added at last"; 
    stringCat(message1,message2); 
    for(i=0;i<50;i++) 
    { 
     printf("%c\n",message1[i]); 
    } 
} 

Программа работает как задумано, чтобы быть и также я получаю такой вывод:

hello whats been up?this should be added at last 

Но я получаю сообщение об ошибке с последующим выходом:

** stack smashing detected : ./a.out terminated ======= Backtrace: ========= */lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted* 

Я пришел, чтобы узнать, почему это происходит от here. Но я не мог понять, почему это происходит в моем коде?

Я новичок в C, мне нужна ваша помощь. Заранее спасибо.

ответ

1

У вас есть переполнение буфера. message1 только имеет достаточно места для хранения message1, не оба и message2. Вам нужно выделить новый char*:

char *stringCat(const char *s, const char *t) 
{ 
    char *r = malloc(strlen(s) + strlen(t) + 1); 
    char *p = r; 

    while(*r++ = *s++); 
    r--; 
    while(*r++ = *t++); 
    *r = '\0'; 

    return p; 
} 

void main() 
{ 
    char message1[] = "hello whats been up?"; 
    char message2[] = "this should be added at last"; 
    char *result = stringCat(message1, message2); 

    printf("%s", result); 

    free(result); 
} 

Here's a demo.

+0

Не забудьте «освободить» буфер –

+1

@NiklasB .: Окончание программы в любом случае, но я положу его туда :) – Ryan

+1

Да, но если он вырастет, правильное управление памятью может стать более важным .. Спасибо (: –

1

Это происходит потому, что просто ваша StringCat функции первого шаг s до конца строки, а затем продолжает увеличить s в неизведанные земли а также увеличивается t.

void stringCat(char *s,char *t) 
{ 
    while(*s++); 
    while((*s++ = *t++)); 
} 

Вы пытаетесь написать t в s за пределы, где есть память, выделенная.

Вам необходимо создать новое пространство памяти с размером s + t + 1 и поместить туда свою конкатенированную строку.

2

char массивы в C не являются точно строками. Когда вы делаете

char hello[] = "Hello"; 

это фактически эквивалентно

char hello[6] = { 'H', 'e', 'l', 'l', 'o', '\0' } 

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

== Как преодолеть: ==

Есть два варианта:

1) Убедитесь, что строка назначения достаточно долго. Это было бы ответственностью вызывающего лица. strcat() работает таким образом.

1b) Вы можете помочь вызывающему абоненту, предоставив им возможность указать размер целевой строки и не записать ее конец. strncat() работает таким образом.

2) Выделите достаточно длинную, третью, целевую строку. Ответственность за освобождение этой строки будет освобождать от звонящего. Примером этого является @minitech. POSIX strdup() работает таким образом.

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