第一次调用addBakeType()后,它将正确地向数组添加新的BakeType对象指针,但是第二次调用后,它似乎在realloc()期间更改了数组的地址,因此指向数组中前一个元素的指针变得混乱了,并且指向错误的记忆。有什么想法如何处理吗?

typedef struct BakeryType {
    char *name;
} BakeType;

BakeType *bakeTypeList=NULL;
int baketypelistcounter=0;


BakeType* addBakeType(char *str){
    baketypelistcounter++;
    bakeTypeList = realloc(bakeTypeList, baketypelistcounter * sizeof (BakeType));
    BakeType *newBakeType = bakeTypeList + baketypelistcounter - 1;
    newBakeType->name=malloc(10* sizeof(char));

    newBakeType->name=str;
    return newBakeType;
}

最佳答案

你不能那样做。重新分配内存并使之更大时,如果后面有另一个内存块,则可能需要移动该内存块,以防止其增长。

您可以避免的选择有:


malloc()每个BakeType分别。因此,列表不是实际的BakeType,而是指针到BakeType的指针。然后将仅移动保存指针的数组。注意,malloc() ed块有开销。因此,如果您的BakeType确实只是一个char*,请摆脱BakeType并直接返回char*。如果您期望更多字段,那可能很好。
而不是返回BakeType*,而是返回baketypelistcounter -1(即索引),并在实际需要时使用bakeTypeList[theIndex]来获取指针。当然,这仅在您只希望添加到列表而从不删除的情况下才有效,因为如果删除较低的索引,则所有较高的索引都会更改。


正如其他人提到的那样,您对姓名的分配是错误的。 malloc() 10个字节,然后用字符串常量的地址覆盖指针。您的代码的正确版本为:

int strByteCount = strlen(str) + 1;
newBakeType->name = malloc(strByteCount * sizeof(char));
memcpy(newBakeType->name, str, strByteCount);


或更短

newBakeType->name = strdup(str);


因为C中的字符串只是malloc()个存储块,所以您的变量仅包含该存储块的地址。因此,将一个字符串分配给另一个字符串不会将一个字符串复制到另一个字符串,而只是引用了另一个字符串。

关于c - 指针在重新分配内存后指向错误的方向,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59182974/

10-11 06:02