难以分配额外的内存吗?

2 c malloc memory-management

我有一个指向最初由 malloc 分配的结构的指针“数组”,当初始容量已满时,我需要通过增量添加额外的内存。当我尝试分配更多内存时,第一个元素似乎消失并导致我的程序崩溃。有人可以帮忙吗?

#include "a2.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int idCompare ( const void * a, const void * b ){
    message *m1 = *(message **)a;
    message *m2 = *(message **)b;
    return m1->messageId - m2->messageId;     
}

int textCompare( const void *a, const void *b ) {
    message *m1 = *(message **)a;
    message *m2 = *(message **)b;
    return strcmp(m1->messageText, m2->messageText);
}

int main(void)
{   
    int id, i;
    int count = 0;

    char cmd[MAX_CMD_LEN];
    char msg_text[MAX_TEXT_LEN];
    message **mList = malloc(INITIAL_CAPACITY * sizeof(message));
    int capacity = INITIAL_CAPACITY * sizeof(message);
    int size = 0;

    while (scanf("%s", cmd)){

        if (!strcmp(cmd, "add")){
            printf("(pre) Capacity =%d, Count =%d, Size =%d\n", capacity, count, size);
            int found = 0;
            scanf("%d\n", &id);
            fgets(msg_text, sizeof(msg_text), stdin);

            if(size >= capacity){
                capacity = size;
                *(mList + count) = malloc(CAPACITY_INCREMENT * sizeof(message));
                message *p = *(mList + count);                    
                if(p == NULL){                                          //If malloc fails, free mList and exit.
                    printf("out of memory\n");
                    free(*mList);
                    exit(1);
                }
            }   

            for(i = 0; i < count; i++){                                 //If existing id is found, send flag & do not add.
                message *p = *(mList + i);
                if(p->messageId == id){  found = 1;  }
            }

            if(!found){                                                
                message *p = *(mList + count);          
                p->messageId = id;
                p->messageText = malloc(strlen(msg_text)+1);    
                strcpy(p->messageText, msg_text);           
                count++;      
                size += 10 * sizeof(message);
                printf("(post) Capacity =%d, Count =%d, Size =%d\n", capacity, count, size);
            }
        }

        else if (!strcmp(cmd, "delete")){                       //Cycle through mList, if id is found, shift elements left.
        scanf("%d", &id);
        for(i = 0; i < count; i++){                
            message *p = *(mList + i);
                if(p->messageId == id){  
                    for(;i < count; i++){*(mList + i) = *(mList + i + 1);}
                    count--;
                    size -= 10 * sizeof(message); 
                }
            }  
        }

        else if (!strcmp(cmd, "find")){                                 //Cycle through mList, if id is matched, print to stdout.
        scanf("%d", &id);
        for(i = 0; i < count; i++){              
            message *p = *(mList + i);
                if(p->messageId == id){  printf("%s", p->messageText);  }
            } 
        }

        else if (!strcmp(cmd, "output")){                       //Cycle through mList, print all to stdout.
        for(i = 0; i < count; i++){
            message *p = *(mList + i);
                printf("%s", p->messageText);
            }
        }

        else if (!strcmp(cmd, "sortById")){  qsort (mList, count, sizeof(message*), idCompare);  }

        else if (!strcmp(cmd, "sortByText")){  qsort (mList, count, sizeof(message*), textCompare);  }

    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Yan*_*min 5

首先,您的消息列表包括

message **mList
Run Code Online (Sandbox Code Playgroud)

但您并没有将其用作指向指针列表的指针。你永远不会分配列表中的指针!

例如,这将是“正确的”(尽管效率低下):

message **mList = malloc(INITIAL_CAPACITY * sizeof(message*));
for (i = 0; i < INITIAL; i++) {
   mList[i] = malloc(sizeof(message));
}
Run Code Online (Sandbox Code Playgroud)

现在您已经有了所表达的数据结构。

但是,您也可以执行:

message *mList = malloc(INITIAL_CAPACITY * sizeof(message));
Run Code Online (Sandbox Code Playgroud)

在所有情况下,一旦解决了内存访问问题,您就可以realloc()就地调整大小。