realloc:程序接收信号信号陷阱、跟踪/断点陷阱

realloc:程序接收信号信号陷阱、跟踪/断点陷阱,c,C,我正在开发一个程序,它可以存储任意长的联系人列表(姓名和电话号码)。条目存储在一个数组中,该数组在每次使用realloc函数添加新元素时都会调整大小。第一个触点可以正常添加和显示。但是,当我尝试添加第二个联系人时,程序崩溃,并显示以下消息: Program received signal SIGTRAP, Trace/breakpoint trap. In ntdll!RtlZeroHeap () (C:\WINDOWS\SYSTEM32\ntdll.dll) 我的编辑器中没有设置断点。调试器

我正在开发一个程序,它可以存储任意长的联系人列表(姓名和电话号码)。条目存储在一个数组中,该数组在每次使用
realloc
函数添加新元素时都会调整大小。第一个触点可以正常添加和显示。但是,当我尝试添加第二个联系人时,程序崩溃,并显示以下消息:

Program received signal SIGTRAP, Trace/breakpoint trap.
In ntdll!RtlZeroHeap () (C:\WINDOWS\SYSTEM32\ntdll.dll)
我的编辑器中没有设置断点。调试器说问题出在包含
realloc
语句的行上。如何解决此问题?我已经包括了下面代码的相关部分

#define STRING_LENGTH 32

typedef struct entry_t {
    char name[STRING_LENGTH];
    char number[STRING_LENGTH];
} Entry;

void *add_entry(Entry*, int);

int main()
{
    int entry_count = 0;
    Entry *entries = calloc(1, sizeof(Entry));
    int choice = 0;

    while (1) {
        printf("Options:\n1) Add Entry\n2) Modify Entry\n3) Print Entries\n4) Exit\n\nSelect an option: ");
        scanf(" %d", &choice);
        switch (choice) {
        case 1:
            entries = add_entry(entries, entry_count++);
            break;
            // ...
        }
    }
}

void *add_entry(Entry *entries, int current_count)
{
    Entry entry;

    printf("Enter name: ");
    scanf(" %[^\n]s", entry.name);
    printf("Enter number: ");
    scanf(" %[^\n]s", entry.number);
    printf("\n");

    entries[current_count] = entry;
    return realloc(entries, sizeof(Entry) * (current_count + 1));
}

这里有一个逻辑问题。最初为一个对象分配空间时使用
calloc
然后调用
add_entry
,计数等于0

然后在索引
current\u count
处添加新条目,此时为0。 然后使用
当前计数+1
调整内存大小,该值也是1。你也是 根本不调整内存大小

在下一次迭代中,
entry\u count
为1,并在
条目[1]
。这就是问题所在,您正在访问外部的内存 边界,因为此时仍然只有一个对象的空间

您不应按当前计数+1重新分配,而应按
current\u count+2
,以便下一次迭代有空间放置新的 内存末尾的元素

void *add_entry(Entry *entries, int current_count)
{
    Entry entry;

    printf("Enter name: ");
    scanf(" %[^\n]s", entry.name);
    printf("Enter number: ");
    scanf(" %[^\n]s", entry.number);
    printf("\n");

    entries[current_count] = entry;
    return realloc(entries, sizeof(Entry) * (current_count + 2));  // <-- +2
}
请注意,
realloc
是计数变量的增量 在同一函数中发生。只有当一切顺利时,你才应该增加 柜台。还请注意,
条目
初始化为
NULL
,因为
realloc(NULL,size)
相当于
malloc(size)

交换最后两行代码我更新了我的答案,为您提供了如何改进此功能的建议。
int main()
{
    size_t entry_count = 0;
    Entry *entries = NULL, *tmp;
    int choice = 0;

    while (1) {
        printf("Options:\n1) Add Entry\n2) Modify Entry\n3) Print Entries\n4) Exit\n\nSelect an option: ");
        scanf(" %d", &choice);
        switch (choice) {
        case 1:
            tmp = add_entry(entries, &entry_count);
            if(tmp == NULL)
            {
                // error handling
                // entries still point to the old memory
                // could be useful in error handling

                free(entries);
                return 1;
            }

            entries = tmp;
            break;
            // ...
        }
    }
}

void *add_entry(Entry *entries, size_t *current_count)
{
    if(current_count == NULL)
        return NULL;

    Entry entry;

    printf("Enter name: ");
    scanf(" %[^\n]s", entry.name);
    printf("Enter number: ");
    scanf(" %[^\n]s", entry.number);
    printf("\n");

    if(entries == NULL)
        *current_count = 0;

    Entry *tmp = realloc(entries, (*current_count + 1) * sizeof *entries);

    if(tmp == NULL)
        return NULL;

    entries = tmp;

    entries[(*current_count)++] = entry;

    return entries;
}