Reallocのしくみを理解できません。バッファをmallocして、そのバッファにデータをコピーした場合、「AB」としましょう。
+------------+
| A | B | \0 |
+------------+
次に、バッファを再割り当てしましたが、データが失われますか(1バイトでも)?;それともバッファを拡張するだけですか? :
+------------------------+
| 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);
}
ブロックのサイズを増やすrealloc
は、元のメモリブロックの内容を保持します。メモリブロックのサイズを変更できない場合でも、古いデータは新しいブロックにコピーされます。ブロックのサイズを縮小するrealloc
の場合、古いデータは切り捨てられます。
realloc
の呼び出しは、何らかの理由でrealloc
が失敗した場合にデータを失うことを意味することに注意してください。これは、realloc
がNULL
を返すことで失敗するためですが、その場合、元のメモリブロックは引き続き有効ですが、ポインタを上書きしたため、アクセスできなくなりますNULL
。
標準パターンは次のとおりです。
_newbuffer = realloc(buffer, newsize);
if (newbuffer == NULL)
{
//handle error
return ...
}
buffer = newbuffer;
_
また、Cではmalloc
からの戻り値のキャストは不要であり、sizeof(char)
は定義により_1
_と等しいことに注意してください。
何も失われません。ただし、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);
}