Мы теряем данные в буфере после 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);
}
Ответы
Ответ 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);
}