Как избавиться от ошибки Stack Smashing? - PullRequest
1 голос
/ 31 марта 2012

У меня есть такой код, который я решаю, выполнив задачу из книги K & R:

#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*

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

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

Ответы [ 3 ]

2 голосов
/ 31 марта 2012

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

char hello[] = "Hello";

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

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

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

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

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

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

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

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

1 голос
/ 31 марта 2012

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

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

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

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

1 голос
/ 31 марта 2012

У вас переполнение буфера. 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);
}

Вот демо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...