C语言编写通讯录realloc问题

用C语言编写通讯录存放联系人信息,开辟动态空间,初始时设置容量为2人,容量满则扩充容量变为4人,但是输入结束后打印,第二个联系人变成乱码。继续扩大容量至6人,第3人与第4人不乱码,只有第二个人发生问题,请问是为什么呢?刚学没多久,好慌乱

头文件中:

//插入头文件
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include
#include
#include
#define NUM 2

struct people
{
    char name[30];
    int age;
    char num[30];
};
struct contact
{
    struct people *data;
    int sz;
    int capacity;

};

//初始化
void first(struct contact* con);
//读文件
void read(struct contact* con);
//添加用户
void Add(struct contact* con);
void write(struct contact* con);
void exit(struct contact* con);

函数源代码:

#include"contact.h"
//初始化
void first(struct contact* con)
{
    struct people*str = (struct people*)malloc(sizeof(struct people));
    if (str == NULL)
    {
        perror(first);
        printf("初始化失败\n");
    }
    else
    {
        con->data = str;       //编译到这里con->data[1]里的内容就变成了一堆问号
        con->sz = 0;
        con->capacity = NUM;
    }
}
//打印出联系人
void show(struct contact* con)
{
    int i = 0;
    printf("%-10s %-10s %-10s\n", "name", "age", "num");
    for (i = 0; i < con->sz; i++)
    {
        printf("%-10s %-10d %-10s\n", con->data[i].name, con->data[i].age, con->data[i].num);
    }
}
//检查是否需要扩容
void Check(struct contact *con)
{
    if (con->sz == con->capacity)
    {
        struct people* str= (struct people*)realloc(con->data, sizeof(struct people) * (NUM + con->capacity));
        if (str == NULL)
        {
            perror(Check);
            printf("增容失败");
            return;
        }
        else
        {
            con->data = str;
            con->capacity += NUM;
            show(con);
        }
    }
    
}
//存入联系人
void Add(struct contact* con)
{
    Check(con);
    printf("请输入姓名:");
    scanf("%s", con->data[con->sz ].name);
    printf("请输入年龄:");
    scanf("%d", &con->data[con->sz].age);
    printf("请输入号码:");
    scanf("%s", con->data[con->sz].num );
    con->sz++;
    printf("输入成功\n");

img

问题出在Add函数中,每次添加联系人时,使用了con->data[con->sz]来存储新的联系人信息,但是在Check函数中,如果需要扩容,重新分配了内存空间,此时con->data指向的是新的内存空间,而之前使用con->data[con->sz]存储的联系人信息并没有被复制到新的内存空间中,因此第二个联系人的信息就变成了乱码。

解决方法是,在Check函数中,重新分配内存空间后,需要将之前存储的联系人信息复制到新的内存空间中。可以使用memcpy函数来实现。
修改后的Check函数如下:

void Check(struct contact *con)
{
    if (con->sz == con->capacity)
    {
        struct people* str= (struct people*)realloc(con->data, sizeof(struct people) * (NUM + con->capacity));
        if (str == NULL)
        {
            perror(Check);
            printf("增容失败");
            return;
        }
        else
        {
            memcpy(str, con->data, sizeof(struct people) * con->sz); //复制联系人信息到新的内存空间中
            con->data = str;
            con->capacity += NUM;
            show(con);
        }
    }
}

  • 这篇博客: C语言 数据结构 栈的数组实现 realloc函数中的 代码 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • rewind(stdin);刷新缓冲区
    void push(Pstack pstack, int num)入栈
    int pop(Pstack pstack)出栈

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<stdlib.h>
    #define MAXSIZE 10
    #define INCREASE 10
    
    //结构体(数组实现栈)
    typedef struct
    {
    	int *base;//栈底下标
    	int *top;//栈顶下标
    	int length;
    }Stack, *Pstack;
    
    //初始化
    void initial(Pstack pstack)
    {
    	pstack->base = NULL;
    	pstack->top = NULL;
    	pstack->length = 0;
    }
    
    //入栈
    void push(Pstack pstack, int num)
    {
    	if (pstack->top == NULL)//如果栈为空
    	{
    		pstack->base = (int*)realloc(pstack->base, sizeof(int));//增加一个空间
    		if (!pstack->base)
    		{
    
    			printf("分配内存错误\n");
    			system("pause");
    		}
    		else
    		{
    			pstack->top = pstack->base;
    			*(pstack->top) = num;//赋值
    			pstack->length++;
    		}
    
    	}
    	else
    	{
    		pstack->base = (int*)realloc(pstack->base, sizeof(int) * (pstack->top - pstack->base + 2));//增加一个空间
    		if (!pstack->base)
    		{
    			printf("分配内存错误\n");
    			system("pause");
    		}
    		else
    		{
    			pstack->top = pstack->base + pstack->length - 1;
    			pstack->top++;
    			*(pstack->top) = num;//赋值
    			pstack->length++;
    		}
    	}
    }
    
    //出栈
    int pop(Pstack pstack)
    {
    	if (pstack->length == 0)
    	{
    		printf("栈为空\n");
    		return -1;
    	}
    	int popper;
    	popper = *(pstack->top);
    	pstack->top--;
    	pstack->length--;
    	return popper;
    }
    
    //打印
    void print(Pstack pstack)
    {
    	int length = pstack->length;
    	printf("输出:");
    
    	for (int i = 0; i < length; i++)
    	{
    		printf("%d ", *(pstack->base + i));
    	}
    	//debug输出指针位置
    	printf("\n");
    	printf("top = %p\n", pstack->top);
    	printf("base = %p\n", pstack->base);
    	printf("length = %d\n", length);
    }
    
    int main()
    {
    	int num;
    	Stack stack;
    	Pstack pstack = &stack;//指向stack的指针
    
    	initial(pstack);
    	printf("入栈:\n");
    	while (scanf("%d", &num) != EOF)
    	{
    		push(pstack, num);
    		print(pstack);
    		rewind(stdin);//刷新缓冲区
    	}
    
    	printf("出栈:输入y/n\n");
    	char checker;
    	while (scanf("%c", &checker) && checker != 'n')
    	{
    		printf("%d已出栈\n", pop(pstack));
    		print(pstack);
    		rewind(stdin);//刷新缓冲区
    	}
    
    	system("pause");
    }
    
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632