使用 memcpy()

问题描述

所以我有这个 Contact 结构和一个包含一堆 Contact 实例的数组。我的问题是我使用 memcpy 并尝试使用 mmove 来“删除”和“添加”联系人元素到这个数组。当我调试和运行程序时,它似乎工作得很好。我可以跟踪从阵列中添加删除的联系人,但是当我在没有调试的情况下运行程序并且没有单步执行程序时,程序崩溃了!

这是我的联系人结构:

typedef struct contact Contact;
typedef struct contact *pContact;
struct contact {
    char lastName[BUFSIZ];
    char firstName[BUFSIZ];
    char email[BUFSIZ];
    char pNumber[BUFSIZ];
};

这是创建联系人的方式:

struct Contact *contactArr[1024];
int size = 0;
Contact* CreateContact(int pos,char *info) {
    Contact *pContactNewContact = (Contact*) malloc(sizeof(Contact));
    char *lastName = strtok(info,",");
    char *firstName = strtok(NULL,");
    char *email = strtok(NULL,");
    char *pNumber = strtok(NULL,");
    if (pContactNewContact) {
        strcpy(pContactNewContact->lastName,lastName);
        strcpy(pContactNewContact->firstName,firstName);
        strcpy(pContactNewContact->email,email);
        strcpy(pContactNewContact->pNumber,pNumber);
    }
    InsertContact(pos,pContactNewContact);
    return pContactNewContact;
}

这些是我的数组操作函数

void InsertContact(int pos,pContact *insert) {
    if (size == 0)
        contactArr[0] = insert;
    else {
        memmove((contactArr + pos + 1),(contactArr + pos),(size + 1) * sizeof(Contact));
        contactArr[pos] = insert;
    }
    size++;
}

void DelContact(int pos) {
    if (pos == 0) {
        memmove(contactArr,(contactArr + 1),(size - 1) * sizeof(Contact));
        contactArr[pos] = 0;
    } else if (pos <= size) {
        memmove((contactArr + pos - 1),(size - pos) * sizeof(Contact));
        contactArr[pos] = 0;
    }
    size--;
}

解决方法

你所有的 sizeof(Contact) 乘法都应该是 sizeof(pContact),因为它是一个指针数组,而不是一个联系人数组。

您移动的金额应该是 size - pos,而不是 size + 1

在覆盖 DelContact 中的位置之前,您需要释放联系人。您不需要为 pos 分配空指针,但您可以将其分配给末尾的额外元素。

删除时不需要特殊情况 pos == 0。使用 pos 的值,所有通用计算都将正常工作。

删除时需要将size - pos减1。

pos <= size 应该是 pos < size

InsertContact 还应该检查您尚未达到阵列的容量。我在下面称其为 maxSize

如果 size 检查失败,您不应增加或减少 if,因为实际上没有任何更改。

void InsertContact(int pos,pContact *insert) {
    if (size == 0) {
        contactArr[0] = insert;
        size = 1;
    } else if (size <= maxSize && pos <= size) {
        memmove(&contactArr[pos+1],&contactArr[pos],(size - pos) * sizeof(pContact));
        contactArr[pos] = insert;
        size++;
    }
}

void DelContact(int pos) {
    if (pos < size) {
        free(contactArr[pos]);
        memmove(&contactArr[pos],&contactArr[pos+1],(size - pos - 1) * sizeof(pContact));
        size--;
        contactArr[size] = 0;
    }
}