Подтвердить что ты не робот

Мы теряем данные в буфере после realloc'ing?

У меня возникают проблемы с пониманием того, как работает realloc. Если я перечислил буфер и скопировал данные в этот буфер, скажем, "AB":

 +------------+
 | A | B | \0 |
 +------------+

то я перераспределяю буфер, будут ли потеряны данные (даже один байт)?; или он просто расширяет буфер?

 +------------------------+
 | A | B | \0 | ? | ? | ? |
 +------------------------+

код:

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

int main(void){

    char* buffer    = (char*) malloc( sizeof(char) * 3 );
    strncpy(buffer, "AB", 2);

    buffer          = (char*) realloc(buffer, sizeof(char) * 6); /* Will there be any lost here? */
    free(buffer);
    return(0);
}
4b9b3361

Ответ 1

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

Обратите внимание, что ваш вызов realloc означает, что вы потеряете свои данные, если по какой-то причине realloc не удается выполнить. Это связано с тем, что realloc завершается неудачей, возвращая NULL, но в этом случае исходный блок памяти остается действительным, но вы больше не можете получить к нему доступ, так как вы перезаписали указатель, будет NULL.

Стандартный шаблон:

newbuffer = realloc(buffer, newsize);
if (newbuffer == NULL)
{
    //handle error
    return ...
}
buffer = newbuffer;

Обратите внимание также, что приведение значения возвращаемого значения из malloc не требуется в C и что sizeof(char) по определению равно 1.

Ответ 2

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

на основе предположения, что вы хотите использовать строки, неправильное использование strncpy

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

int main(void) {
    char *buffer = malloc(3);
    if (buffer == NULL) /* no memory */ exit(EXIT_FAILURE);

    strncpy(buffer, "AB", 2);
    /* ATTENTTION! ATTENTION: your array is not a string.
    ** buffer[2] is not the zero string terminator */

    // buffer = realloc(buffer, 6); /* Will there be any lost here? */
    /* If realloc returns NULL, you've just lost the only pointer to
    ** the allocalted memory, by overwriting it with NULL.
    ** Always `realloc` to a temporary variable */
    char *tmp_buffer = realloc(buffer, 6);
    if (tmp_buffer == NULL) {
        /* realloc failed */
    } else {
        /* realloc worked, no bytes lost */
        buffer = tmp_buffer;
        /* ATTENTION! ATTENTION: buffer is still not a string
        ** buffer[0] is 'A', buffer[1] is 'B',
        ** all other elements of buffer are indeterminate */
    }

    free(buffer);
    return(0);
}