2016-12-08 2 views
-1

Я новичок в C, и я хочу создать динамический массив для хранения строк. Я написал код ниже, но это не сработало. Элементы массива содержат некоторые символы ASCII вместо строки. Я хочу historyArray[0] значение будет "foo". Как я могу это сделать?Динамическая структура массива строк в C

typedef struct { 
    char *historyCommand; 
    int usedSize; 
    int maximumSize; 
} HistoryArray; 

void CreateHistoryArray(HistoryArray *HistoryArray) { 
    HistoryArray->historyCommand = (char *) malloc(sizeof(char) * MAX_LEN); 
    HistoryArray->usedSize = 0; 
    HistoryArray->maximumSize = INITIAL_SIZE; 
} 

void ExpandHistoryArray(HistoryArray *HistoryArray, int newSize) { 
    int *newArray = (char *) malloc(sizeof(char) * newSize); 
    memcpy(newArray, HistoryArray->historyCommand, sizeof(char) * HistoryArray->maximumSize); 
    free(HistoryArray->historyCommand); 
    HistoryArray->historyCommand = newArray; 
    HistoryArray->maximumSize = newSize; 
} 

void AddHistoryValue(HistoryArray *HistoryArray, char historyCommand[]) { 
    strcpy(HistoryArray->historyCommand[HistoryArray->usedSize], historyCommand); 

    HistoryArray->usedSize++; 

    if (HistoryArray->usedSize == HistoryArray->maximumSize) { 
     ExpandHistoryArray(HistoryArray, HistoryArray->maximumSize * 2); 
    } 
} 

void freeHistoryArray(HistoryArray *a) { 
    free(a->historyCommand); 
    a->historyCommand = NULL; 
    a->usedSize = 0; 
    a->maximumSize = 2; 
} 


HistoryArray historyArray; 
+0

Пожалуйста, укажите [mcve]. Как и какие функции вы вызываете? «Я хочу, чтобы значение historyArray [0] было« foo ». Это не имеет смысла.' HistoryArray [0] 'не является массивом' char'. Пожалуйста, уточните в своем описании. И, пожалуйста, отформатируйте свой код с правильным отступом чтобы сделать его доступным для чтения. – kaylum

+0

'char * HistoryArray' не является массивом строк, это массив символов, который представляет собой только одну строку. – Barmar

+0

' BTW', 'malloc + memcpy + free' - это то же самое, что' realloc' – Barmar

ответ

1

В вашем коде есть ряд проблем.

  1. char *historyCommand является указателем на одну строку, а не массив строк. Для указателя на массив строк вы должны использовать char **historyCommand.

  2. Вам не нужно выделять пространство для отдельных строк при создании HistoryArray. Вы можете выделить достаточное количество места при каждом добавлении в массив, используя длину добавляемой строки.

  3. Вместо того, чтобы звонить malloc(), memcpy() и free(). Это имеет то преимущество, что иногда оно может просто расширить выделенную память, поэтому копирование не потребуется.

  4. Когда вы освобождаете HistoryArray, вам необходимо освободить все строки. Вы не должны освобождать historyCommand, потому что вы установили maximumSize = 2, а другие функции предположили, что это означает, что есть место для 2 предметов, что неверно, если вы установили historyCommand в NULL. Поэтому вы должны изменить размер до maximumSize, чтобы соответствовать остальной части кода.

Вот новый код:

typedef struct { 
    char **historyCommand; 
    int usedSize; 
    int maximumSize; 
} HistoryArray; 

void CreateHistoryArray(HistoryArray *HistoryArray) { 
    HistoryArray->historyCommand = malloc(INITIAL_SIZE * sizeof(char *)); 
    HistoryArray->usedSize = 0; 
    HistoryArray->maximumSize = INITIAL_SIZE; 
} 

void ExpandHistoryArray(HistoryArray *HistoryArray, int newSize) { 
    HistoryArray->historyCommand = realloc(HistoryArray->historyCommand, newSize * sizeof(char *)); 
    HistoryArray->maximumSize = newSize; 
} 

void AddHistoryValue(HistoryArray *HistoryArray, char historyCommand[]) { 
    historyCommand[HistoryArray->usedSize] = malloc(strlen(historyCommand) + 1); 
    strcpy(HistoryArray->historyCommand[HistoryArray->usedSize], historyCommand); 

    HistoryArray->usedSize++; 

    if (HistoryArray->usedSize == HistoryArray->maximumSize) { 
     ExpandHistoryArray(HistoryArray, HistoryArray->maximumSize * 2); 
    } 
} 

void freeHistoryArray(HistoryArray *a) { 
    for (int i = 0; i < a->usedSize; i++) { 
     free a->historyCommand[i]; 
    } 
    a->usedSize = 0; 
    a->maximumSize = 2; 
    a->historyCommand = realloc(a->historyCommand, a->maximumSize * sizeof(char *)); 
} 

HistoryArray historyArray; 
+0

он работает! Спасибо большое! –

Смежные вопросы