簡體   English   中英

如何最小化 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 錯誤。

如果您只想刪除一個條目,您實際上並不需要另一個臨時數組。 你所要做的就是:

  1. 找到您要刪除的條目(您可能已經有了索引,或者您可能想要搜索內容)。
  2. 釋放該條目。
  3. 將所有其他條目移回一個 position (或者只是移動最后一個來代替已刪除的那個,如果您不關心訂單,這會更快)。
  4. 使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM