2016-06-23 6 views
1

Я пытаюсь выполнить две строки, предполагая, что строка «dest» не имеет достаточного пространства для добавления другой, поэтому я использую динамические массивы для ее решения.Использование realloc для concat строк

Ошибка при попытке скомпилировать код. Ошибка mremap_chunk.

Я не знаю, что я пропускаю, так как вызов перераспределить имеет все права Params место в


Ошибка.

malloc.c:2869: mremap_chunk: Assertion `((size + offset) & (GLRO (dl_pagesize) - 1)) == 0' failed. 
Aborted (core dumped) 

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

char *strcatt(char *s1, char *s2) 
{ 
    int a = strlen(s1); 
    int b = strlen(s2); 
    int i, size_ab = a+b; 

    s1 = (char *) realloc (s1, size_ab*sizeof(char)); 

    for(i=0; i<b; i++) { 
     s1[i+a]=s2[i]; 
    } 

    s1[size_ab]='\0'; 

    return s1; 
} 


int main() 
{ 
    char s1[]="12345"; 
    char s2[]="qwerty"; 

    strcatt(s1,s2); 
    printf("%s\n", s1); 

    return 0; 
} 
+0

Заменить 'size_ab = a + b' на' size_ab = a + b + 1' – GMichael

ответ

2

Во-первых, вы обрабатываете память без кучи как память кучи, не делайте этого.

Во-вторых, вы не включаете место для терминатора в расчете.

Вот еще некоторые моменты:

  1. Не называйте функции, начиная с str, это зарезервированное пространство имен.
  2. Размер буфера должен быть size_t, а не int.
  3. Don't cast the return value of malloc() in C.
  4. Используйте memcpy() для копирования блоков памяти, когда знаете размер.
  5. Строки с правой стороны должны быть const.
  6. Сделка с возможностью ошибки распределения.
  7. Я считаю это плохой практикой масштабе sizeof (char), что всегда 1.

Вот как я бы написать, исходя из той же логики:

char * my_strcatt(char *s1, const char *s2) 
{ 
    const size_t a = strlen(s1); 
    const size_T b = strlen(s2); 
    const size_ab = a + b + 1; 

    s1 = realloc(s1, size_ab); 

    memcpy(s1 + a, s2, b + 1); 

    return s1; 
} 
+1

Не является ли настоящая проблема перераспределением автоматического массива? –

+0

@MohitJain Heh. Да, конечно. Я не сделал это для чтения 'main()'. Хороший улов! – unwind

3

Вы не можете realloc или free память который не выделяется вызовом malloc или не является NULL.

Из раздела 7.22.3.5. Функция перераспределить в C11 проекте

The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.

Итак, s1 = (char *) realloc (s1, size_ab*sizeof(char)); корне неверно для входов (автоматические массивы), никогда не делать этого.

И еще есть много проблем, которые могут быть исправлены с помощью отладчика.

+0

Вы _cannot_ ... – artm

+0

@artm Спасибо за указание. Спасибо Иоганну за исправление. –

1

лязг отладчик дает очень четкое описание ошибки:

malloc: error for object 0x7fff6fbb16d6: pointer being realloc'd was not allocated 
set a breakpoint in malloc_error_break to debug 

Оба ваших массивов инициализируются как строковые литералы.Кроме того, ваша функция пытается изменить строковый литерал, перераспределяя его, то есть wrong по стандарту C, потому что вы не можете перераспределить то, что вы не выделили, а затем скопировать элементы второго строкового литерала на «объект», который вы предназначенный для изменения путем неправильного использования realloc() в строковом литерале.

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

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

char *mystrcatt(char *s1, char *s2) 
{ 
    int a = strlen(s1); 
    int b = strlen(s2); 
    int i, size_ab = a+b; 

    char *s3 = malloc (size_ab*sizeof(char)); //sizeof(char) is always 1 

    for(i=0; i<a; i++) { //inefficient 
     (s3[i])=s1[i]; 
    }  

    for(i=0; i<b; i++) { //inefficient 
     (s3[i+a])=s2[i]; 
    } 

    s3[size_ab]='\0'; 

    return s3; 
} 


int main() 
{ 
    char s1[]="12345"; 
    char s2[]="qwerty"; 
    char *s3 = mystrcatt(s1,s2);  
    printf("%s\n", s3); 
    free(s3); 
    return 0; 
} 

Пожалуйста, также обратите внимание, что вас don't cast возвращение malloc() в C.

+0

'gdb' - отладчик для' gcc'. Что такое отладчик для «clang»? – artm

+1

'lldb' - это то, о чем вы просите. Вот ссылка [http://lldb.llvm.org]. Спасибо за ваш вклад. – user3078414

+0

круто это новое для меня - спасибо за ссылку – artm