我有这个指向最初由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;
}
答案 0 :(得分:4)
首先,您的消息列表包含
message **mList
但是你没有将它用作指向指针列表的指针。你永远不会在列表中分配指针!
例如,这将是“正确的”(尽管效率低下):
message **mList = malloc(INITIAL_CAPACITY * sizeof(message*));
for (i = 0; i < INITIAL; i++) {
mList[i] = malloc(sizeof(message));
}
现在您拥有了自己表达的数据结构。
但是,你也可以执行:
message *mList = malloc(INITIAL_CAPACITY * sizeof(message));
在所有情况下,一旦解决了内存访问问题,就可以使用realloc()
调整其大小。
答案 1 :(得分:0)
您需要使用realloc()
来分配更大的内存块。
realloc()
将分配一个新块(如果需要),将原始数据复制到新块,并释放旧块(如果需要)。
如果您再次调用malloc()
,则会为新内存块分配新值。这也意味着你已经创建了内存泄漏,因为你的原始内存块没有被释放。
答案 2 :(得分:0)
至少从事物的外观来看,你错误地定义了mlist
:
message **mList = malloc(INITIAL_CAPACITY * sizeof(message));
由于您为message
结构分配空间,看起来mList
应该只是message *
:
message *mList = malloc(INITIAL_CAPACITY * sizeof(message));
或(我通常喜欢的):
message *mList = malloc(INITIAL_CAPACITY * sizeof(*mList));
总的来说,你的代码似乎让两个相当不同的案例混淆不清。一个是你动态分配一个message
的数组,另一个是你正在分配一个指向消息的指针数组。虽然这个问题并不完全重复,但我之前发布了answer图表,以图形方式显示差异。
虽然其他答案是正确的,realloc
通常对扩展分配很有用,但我认为你需要多考虑一下你正在扩展的内容:message
的数组,或指针数组,每个实际message
分别分配。从事物的外观来看,message
结构本身包含一个指向消息实际文本的指针,它与message
结构本身分开分配。在这种情况下,可能更有意义地分配消息对象数组而不是指针数组。