问题
I've allocated a string with the calloc function:
//string1 and string2 previously declared
char *stringClone = calloc(strlen(string1) + 1, sizeof(char));
Now I want to do the same thing on stringClone with a different string. Doing:
stringClone = calloc(strlen(string2) + 1, sizeof(char));
I'm gonna have some memory leak, right? How should I use the realloc in this case?
回答1:
You can use realloc()
to reallocate memory allocated by malloc()
, calloc()
, realloc()
, aligned_alloc()
or strdup()
. Note that if the reallocated block is larger than the original block returned by calloc()
, the newly allocated portion will not be initialized to all bits zero.
Note however that the syntax for realloc()
is not what you use: you must pass the pointer as the first argument and a single size_t
for the new size. Furthermore, if a new block cannot be allocated, NULL
is returned and the block is not freed, hence you should not store the return value directly to stringClone
.
If you want to use realloc()
, here is what you should do:
//string1 and string2 previously declared
char *stringClone = calloc(strlen(string1) + 1, 1);
...
char *newp = realloc(stringClone, strlen(string2) + 1);
if (newp == NULL) {
// deal with out of memory condition
free(stringClone);
}
Since you do not seem to care that the contents of stringClone
be preserved in the the reallocated block, you should probably simply write:
//string1 and string2 previously declared
char *stringClone = calloc(strlen(string1) + 1, 1);
if (stringClone == NULL) {
// deal with out of memory condition
...
}
strcpy(stringClone, string1);
...
free(stringClone);
stringClone = calloc(strlen(string2) + 1, 1);
if (stringClone == NULL) {
// deal with out of memory condition
...
}
strcpy(stringClone, string2);
Note also that on POSIX compliant systems, there is a memory allocation function that is very useful for your use case: strdup(s)
takes a pointer to a C string, allocates strlen(s) + 1
bytes, copies the string to the allocated block and returns it:
//string1 and string2 previously declared
char *stringClone = strdup(string1);
if (stringClone == NULL) {
// deal with out of memory condition
...
}
...
free(stringClone);
stringClone = strdup(string2);
if (stringClone == NULL) {
// deal with out of memory condition
...
}
Note also that casting the return value of malloc
, calloc
and realloc
is unnecessary in C and considered bad style.
回答2:
The reason to use realloc
is that it keeps the original data intact. However, if I understand your use-case correctly, you intend to erase the original data. In that case, it is simpler and clearer to just write:
char *stringClone = calloc(strlen(string1) + 1, sizeof(char));
// check for calloc error
// use stringClone for string1
free(stringClone);
stringClone = calloc(strlen(string2) + 1, sizeof(char));
// check for calloc error
// use stringClone for string2
The error-checking is simpler for calloc
than for realloc
, since no temporary variable is needed. Also, this pattern makes it clear that the array contents for string1
and string2
are not related.
来源:https://stackoverflow.com/questions/56831704/how-to-realloc-some-memory-allocated-using-calloc