2015-08-20 2 views
0
void replace(char *str) { 
    unsigned int len = 0; 
    unsigned int no_of_spaces = 0; 
    while (*str) { 
     if ((char)*str == SPACE) 
      no_of_spaces++; 
     str++; 
     len++; 
    } 

    unsigned int new_len = len + 2 * no_of_spaces; 
    str = (char*) realloc(str, new_len * sizeof(char)); 
    str[new_len] = '\0'; 
} 

Я использую функцию как replace("random string");.Получение (сбрасывание сердечника) при использовании realloc

Здесь я пытаюсь увеличить размер строки, чтобы пробелы могли быть заменены другой строкой. Для этого мне нужно подсчитать количество пробелов и получить длину исходной строки. Я смог это сделать.

Для изменения размера Я использую realloc, но когда я запускаю его, он дает Aborted (core dumped)?

+1

realloc возвращает NULL, если вызов завершается с ошибкой, вы должны это проверить ..... –

+1

Покажите, как вы называете 'replace' и что вы передаете параметру ass для' replace'. –

+0

См. Также: [Я делаю результат 'malloc'?] (Http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Sebivor

ответ

1

Эта строка неверна, так как допустимые показатели варьируются от 0 .. new_len - 1:

str[new_len] = '\0'; 

Это, вероятно, следует:

str[new_len - 1] = '\0'; 

У вас также есть несколько других потенциальных проблем:

  • realloc может возвращать NULL - вы должны проверить это

  • В случае, если realloc не удался, вы потеряли свой оригинальный указатель str и получите утечку памяти - вы должны использовать указатель температуры для результата, проверить это для NULL, а затем только если realloc преуспел, если вы установите str равной температуре:


char * temp = realloc(str, new_len); 
if (temp == NULL) 
{ 
    // handle error here... 
} 
else 
{ 
    str = temp; // success... 
    str[new_len - 1] = '\0'; 
} 

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

Я изменил это, но я все равно получаю ту же ошибку! –

+1

Ну, вам нужно исправить * все * ошибки - это всего лишь один из них. –

7

Была ли ваша исходная строка выделена с помощью malloc? или realloc? Возможно, вы пытаетесь увеличить размер статической строки (строковый литерал):

char sStatic[256]; // cannot realloc 

char *sNonStatic = NULL; // can/must realloc 

replace("random string") // cannot realloc within replace 

EDIT: после прочтения вашего комментария, вы должны взять копию входящей строки, увеличить размер, то вывести копию/новая строка. Вы не можете увеличить размер постоянной строки (строковый литерал).

+1

Хорошая догадка - не подумал об этом! –

+0

Я прямо передаю строку в качестве аргумента, например 'replace (" random string ")'. –

+2

Ответ исправлен. Вы не можете увеличить эту постоянную строку – Grantly

5

Единственные указателей, которые могут быть переданы в realloc нулевые указатели и те, которые были возвращены на calloc, malloc или realloc ранее!

Это важно, потому что вы сказали, что вы назвали вашу функцию как replace("random string") ... Является ли "random string" пустой указатель, или возвращается один из этих *alloc функций? Возможно, вы хотели использовать strdup или что-то (например, char *foo = strdup("random string"); replace(foo); free(foo);)? strdup - это функция POSIX (например, не такая C-стандартная функция, как функции *alloc), но она должна вернуть что-то, возвращаемое функциями *alloc.


После этого кода:

unsigned int new_len = len + 2 * no_of_spaces; 
str = (char*) realloc(str, new_len * sizeof(char)); /* NOTE there's a potential memory leak 
                * when realloc returns NULL here, though 
                * that's the least of your problems */ 

... вы должны проверить str обеспечить realloc удалось, и только тогда допустимы только индексы для str между 0 и new_len - 1. Это либо нулевой указатель разыменования или переполнение буфера:

str[new_len] = '\0'; 

Возможно, вы имели в виду следующее:

size_t new_len = len + 2 * no_of_spaces; 
void *temp = realloc(str, new_len + 1); /* <--- NOTE +1 HERE! */ 
if (temp == NULL) { 
    /* XXX: Bomb out due to allocation failure */ 
} 
str = temp; 

... и теперь действительные индексы от 0 до new_len + 1 - 1, так это справедливо :

str[new_len] = '\0'; 
+0

Я вижу, что вы не использовали 'realloc' для' char * '. Отличается ли неправильный путь? –

+1

@AnimeshPandey См. [Я делаю результат 'malloc'?] (Http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Sebivor

0

Вы также переместить указатель

while (*str) { 
    if ((char)*str == SPACE) 
     no_of_spaces++; 
    str++; 
    len++; 
} 

и когда вы в конце, вы пытаетесь перераспределить его. Но вы уже далеко от массива. Здесь используется переменная temp. И как говорили другие. Строка, мы надеемся, создана с помощью malloc, а не как массив.

И str[new_len] = '\0'; находится за пределами.

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