Ошибка объединения строк с выделением динамической памяти malloc

Ошибка конкатенации строки *char с выделением динамической памяти malloc

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

Заранее спасибо!

char *buf;

int main(void) {
    // ...

    WriteString("#INIT.\r\n"); //serial output

    buf = "";

    while(1)
    {
        char *str1 = "qwe";
        char *str2 = "asd";
        char *str3 = "zxc";
        char *str4 = "123";

        buf = my_strcat(buf,str1);
        buf = my_strcat(buf,str2);
        buf = my_strcat(buf,str3);
        buf = my_strcat(buf,str4);

        WriteString(buf); //serial output

        free(buf);
    }
}

char *my_strcat(const char *str1, const char *str2) {
    char *new_str;
    new_str = malloc(strlen(str1)+strlen(str2)+1);
    new_str[0] = '\0';
    strcat(new_str,str1);
    strcat(new_str,str2);
    return new_str;
}

Серийный выход...

#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
#INIT.
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123
qweasdzxc123

person Marco Costa    schedule 08.01.2015    source источник


Ответы (3)


Ваш первый вызов my_strcat имеет неопределенное поведение, поскольку buf раньше не был инициализирован. именно в этой строчке проблема

new_str = malloc(strlen(str1)+strlen(str2)+1);

strlen(str1), где str1 не инициализировано.

Предложение, используйте realloc

char *my_strcat(char *str1, const char *str2)
{
    char  *new_str;
    size_t length;
    size_t str1length;

    if (str2 == NULL)
        return str1;
    str1length = 0;
    if (str1 != NULL)
        str1length = strlen(str1);
    length  = strlen(str2) + str1length;
    new_str = realloc(str1, 1 + length);
    if (new_str == NULL)
        return str1;
    new_str[str1length] = '\0';

    strcat(new_str, str2);

    return new_str;
}

а также

char *buf;
char *str1 = "qwe";
char *str2 = "asd";
char *str3 = "zxc";
char *str4 = "123";

buf = NULL;
buf = my_strcat(buf, str1);
buf = my_strcat(buf, str2);
buf = my_strcat(buf, str3);
buf = my_strcat(buf, str4);
person Iharob Al Asimi    schedule 08.01.2015
comment
затем переместите эту строку buf = ""; внутрь цикла, так как в последующих вызовах вы используете free'd buf, но все же ваше решение приведет к утечке памяти, как указывает ответ R Sahu, вы должны попробовать мой realloc версия. - person Iharob Al Asimi; 08.01.2015
comment
РАБОТАЕТ! Ты обалденный! Спасибо! - person Marco Costa; 08.01.2015
comment
iharob, *buf должен быть глобальным, чтобы к нему могли обращаться другие методы, такие как буфер печати. - person Marco Costa; 25.01.2015
comment
Это не очень хорошая причина, сделайте так, чтобы каждая функция, которой требуется доступ к buf, принимала параметр указателя char и передала ему buf, функции, которые работают с глобальной переменной, не имеют большого смысла, например, вы не можете повторно использовать их код. По возможности избегайте глобальных переменных. - person Iharob Al Asimi; 25.01.2015

У вас есть утечки памяти в цикле while и не хватает памяти.

    buf = my_strcat(buf,str1); // Got some new memory
    buf = my_strcat(buf,str2); // Got some more new memory without freeing the previous memory
                               // The previous memory is lost. You don't even have a pointer 
                               // to it any more.

    buf = my_strcat(buf,str3); // Ditto
    buf = my_strcat(buf,str4); // Ditto

Что вам нужно:

    char* temp = NULL
    buf = my_strcat(buf,str1);
    temp = buf;

    buf = my_strcat(temp,str2);
    free(temp);
    temp = buf;

    buf = my_strcat(temp,str3);
    free(temp);
    temp = buf;

    buf = my_strcat(temp,str4);
    free(temp);
person R Sahu    schedule 08.01.2015
comment
Это правда об утечках памяти, но вызывает ли это проблему примерно после 15 итераций? - person chux - Reinstate Monica; 08.01.2015
comment
@chux, хорошая мысль о 15 итерациях. В опубликованном коде OP могут быть другие проблемы. Их вывод не соответствует коду. - person R Sahu; 08.01.2015

Ваше использование buf нелогично. Вы не показали, как она была распределена, но даже если вы сделали malloc() памяти для buf, вы перезаписали ее с помощью

    buf = "";

Затем у вас есть бесконечный цикл без условия выхода

while(1) {
    ...    
}

который будет продолжать попытки конкатенации, пока компьютер не загорится. Хуже того, в конце цикла while() вы

free(buf);

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

person Weather Vane    schedule 08.01.2015