如何最小化 C 中动态分配的字符串数组?
How do I minimize a dynamically allocated string array in C?
如何减小动态分配的字符串数组的大小?
int main(){
char **a = malloc(sizeof(char *)*5);
for (int i = 0; i < 5; i++){
a[i] = malloc(sizeof(char) * 10);
}
strcpy(a[0], "apple");
strcpy(a[1], "cat");
strcpy(a[2], "dog");
strcpy(a[3], "sun");
strcpy(a[4], "moon");
//Now I want to get rid of dog and resize the array to 5
}
我试过像这样创建新的动态字符串数组:
char **temp_storage = malloc(sizeof(char *) * 4);
for (int i = 0; i < 4; i++){
temp_storage[i] = malloc(sizeof(char) * 10);
}
然后复制所有元素从 'a' 到 'temp_storage' 除了 'dog'。
一切完成后,我释放 'a'
中的所有元素
for (int i = 0; i < 5; i++){
free(a[i]);
a[i] = NULL;
}
然后我将 a 重新分配为 4 的大小。并将 'temp_storage' 中的所有元素复制到 'a'。
但我一直收到 AddressSanitizer 错误。
如果你只想删除一个条目,你真的不需要另一个临时数组。您所要做的就是:
- 找到您要删除的条目(您可能已经有了索引,或者您可能想要搜索内容)。
- 释放该条目。
- 将所有其他条目移回一个位置(或者只将最后一个条目移动到已删除条目的位置,如果您不关心顺序,这样会更快)。
- 使用
realloc()
重新分配以调整数组大小。
这是一个例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ENTRY_SIZE 10
int main(void) {
size_t size = 5;
char **arr, **tmp;
size_t i;
arr = malloc(sizeof(char *) * size);
if (arr == NULL) {
perror("malloc failed");
return 1;
}
for (i = 0; i < size; i++) {
arr[i] = malloc(sizeof(char) * ENTRY_SIZE);
if (arr[i] == NULL) {
perror("malloc failed");
return 1;
}
}
strcpy(arr[0], "apple");
strcpy(arr[1], "cat");
strcpy(arr[2], "dog");
strcpy(arr[3], "sun");
strcpy(arr[4], "moon");
// Search for "dog" and remove it if found
for (i = 0; i < size; i++) {
if (!strcmp(arr[i], "dog")) {
free(arr[i]);
break;
}
}
// If "dog" was found and removed
if (i < size) {
// Move all elements after "dog" back one position
for (; i < size - 1; i++)
arr[i] = arr[i + 1];
// Resize the array
size--;
tmp = realloc(arr, sizeof(char *) * size);
if (tmp == NULL) {
perror("realloc failed");
return 1;
}
arr = tmp;
}
// Print everything to show the results
for (i = 0; i < size; i++)
printf("%d: %s\n", i, arr[i]);
// Free everything
for (i = 0; i < size; i++)
free(arr[i]);
free(arr);
return 0;
}
结果:
0: apple
1: cat
2: sun
3: moon
如果不在意元素的顺序,可以不用全部移动,只需要移动最后一个代替删除的:
if (i < size) {
arr[i] = arr[size - 1];
size--;
tmp = realloc(arr, sizeof(char *) * size);
// Same as above...
}
结果:
0: apple
1: cat
2: moon
3: sun
如何减小动态分配的字符串数组的大小?
int main(){
char **a = malloc(sizeof(char *)*5);
for (int i = 0; i < 5; i++){
a[i] = malloc(sizeof(char) * 10);
}
strcpy(a[0], "apple");
strcpy(a[1], "cat");
strcpy(a[2], "dog");
strcpy(a[3], "sun");
strcpy(a[4], "moon");
//Now I want to get rid of dog and resize the array to 5
}
我试过像这样创建新的动态字符串数组:
char **temp_storage = malloc(sizeof(char *) * 4);
for (int i = 0; i < 4; i++){
temp_storage[i] = malloc(sizeof(char) * 10);
}
然后复制所有元素从 'a' 到 'temp_storage' 除了 'dog'。 一切完成后,我释放 'a'
中的所有元素for (int i = 0; i < 5; i++){
free(a[i]);
a[i] = NULL;
}
然后我将 a 重新分配为 4 的大小。并将 'temp_storage' 中的所有元素复制到 'a'。
但我一直收到 AddressSanitizer 错误。
如果你只想删除一个条目,你真的不需要另一个临时数组。您所要做的就是:
- 找到您要删除的条目(您可能已经有了索引,或者您可能想要搜索内容)。
- 释放该条目。
- 将所有其他条目移回一个位置(或者只将最后一个条目移动到已删除条目的位置,如果您不关心顺序,这样会更快)。
- 使用
realloc()
重新分配以调整数组大小。
这是一个例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ENTRY_SIZE 10
int main(void) {
size_t size = 5;
char **arr, **tmp;
size_t i;
arr = malloc(sizeof(char *) * size);
if (arr == NULL) {
perror("malloc failed");
return 1;
}
for (i = 0; i < size; i++) {
arr[i] = malloc(sizeof(char) * ENTRY_SIZE);
if (arr[i] == NULL) {
perror("malloc failed");
return 1;
}
}
strcpy(arr[0], "apple");
strcpy(arr[1], "cat");
strcpy(arr[2], "dog");
strcpy(arr[3], "sun");
strcpy(arr[4], "moon");
// Search for "dog" and remove it if found
for (i = 0; i < size; i++) {
if (!strcmp(arr[i], "dog")) {
free(arr[i]);
break;
}
}
// If "dog" was found and removed
if (i < size) {
// Move all elements after "dog" back one position
for (; i < size - 1; i++)
arr[i] = arr[i + 1];
// Resize the array
size--;
tmp = realloc(arr, sizeof(char *) * size);
if (tmp == NULL) {
perror("realloc failed");
return 1;
}
arr = tmp;
}
// Print everything to show the results
for (i = 0; i < size; i++)
printf("%d: %s\n", i, arr[i]);
// Free everything
for (i = 0; i < size; i++)
free(arr[i]);
free(arr);
return 0;
}
结果:
0: apple
1: cat
2: sun
3: moon
如果不在意元素的顺序,可以不用全部移动,只需要移动最后一个代替删除的:
if (i < size) {
arr[i] = arr[size - 1];
size--;
tmp = realloc(arr, sizeof(char *) * size);
// Same as above...
}
结果:
0: apple
1: cat
2: moon
3: sun