gpt4 book ai didi

c - 挣扎与malloc/realloc和结构

转载 作者:行者123 更新时间:2023-11-30 15:05:04 25 4
gpt4 key购买 nike

我真的很难理解在C中使用结构时使用mallocrealloc时实际发生的情况。我试图解决电话簿问题,必须创建一个可以添加,删除和显示条目的电话簿。 。条目数可以无限,因此我必须动态定义结构数组。我的删除功能还必须找到所需的条目,然后移回所有条目,然后使用realloc释放最后一个条目。我认为,这是对realloc的基本理解会真正帮助我的地方。

我认为我能正常工作的唯一部分是添加功能,我仍然不知道我是否正确设置了它-我只知道它在运行时就可以正常工作。如果某个基本水平的人可以帮助我,我将不胜感激。

这是我的一堆代码:-(

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void getEntry(int *);
typedef struct person {
char fname[20];
char lname[20];
int number[10];
}person;
void getInfo(int *,int,person*);
void delInfo(int*,int,person*);
void showInfo(int*,int,person*);

int main(){

int a=0;
int i=0;
int con=0;
person* contacts=(person*)malloc(sizeof(person));
person* pcontacts;
pcontacts=(person*)calloc(0,sizeof(person));
getEntry(&a);
while (a!=4){
switch (a){
case 1:
pcontacts=(person*)realloc(pcontacts,con* sizeof(person));
getInfo(&con,i,contacts);
break;
case 2:
delInfo(&con,i,contacts);
break;
case 3:
showInfo(&con,i,contacts);
break;
default:
printf("\n Error in response. Please try again: ");
break;
}
getEntry(&a);
}
printf("\n Thank you for using the Phone Book Application!\n\n");
free(contacts);
return 0;
}

void getEntry(int *a1){
int b;
printf("\n\n\n Phone Book Application\n\n 1) Add Friend\n 2) Delete Friend\n 3) Show Phone Book Entries\n 4) Exit\n\n Make a selection: ");
scanf("%d",&b);
*a1 = b;
}
void getInfo(int *con,int i,person*contacts){
printf("\n Enter first name: ");
scanf("%s",contacts[*con].fname);
printf(" Enter last name: ");
scanf("%s",contacts[*con].lname);
printf(" Enter telephone number without spaces or hyphens: ");
scanf("%d",contacts[*con].number);
(*con)++;
printf("\n Entry Saved.");
}
void delInfo(int *con,int i,person*contacts){
char delfirst[20];
char dellast[20];

printf("\n First Name: ");
scanf("%s",delfirst);
printf(" Last Name: ");
scanf("%s",dellast);

for (i=0; i<*con;i++){
if (delfirst==contacts[i].fname && dellast==contacts[i].lname){

}
}
}
void showInfo(int *con,int i,person*contacts){
char nullstr[1]={"\0"};
if (*con>0){
printf("\n Current Listings:\n");
for (i=0;i<*con;i++){
if (strcmp(nullstr,contacts[i].fname)!=0){
printf(" %s %s %i\n",contacts[i].fname,contacts[i].lname,contacts[i].number);
}
else {};
}
}
else {
printf("\n No Entries\n");
}
}

最佳答案

首先,让我澄清另一个答案中提出的观点:


  关于可移植性的警告:根据《 GNU C库参考手册》,ISO C之前的实现可能不支持此行为。


除非您正在使用具有数十年历史的嵌入式硬件及其专有的编译器,否则,您很少(如果有的话)会遇到至少不支持C89(ANSI C)标准的编译器。



现在已经解决了,让我们继续进行malloc()realloc()。要了解后者,让我们看一下前者。

malloc()man page指出以下内容:


  malloc()。 。 。 [和] realloc()。 。 。函数分配内存。对齐分配的内存,以便可以将其用于任何数据类型。 。 。 free()函数释放通过前面的分配函数创建的分配。


这种帮助我们。基本上,您的操作系统“拥有”计算机上物理安装的所有可用内存。系统将在swap space处分配所有RAM,kernel level等。

但是,用户空间中的进程(例如您的程序)不希望/不需要管理系统中的所有内存-更不用说所涉及的安全风险了(请考虑一下,如果我可以随意地在另一个进程中编辑内存,而无需安防措施!)。

因此,操作系统将管理进程的内存以及该进程使用的系统内存的allocate不同部分。

一般而言,操作系统将内存划分为所谓的块或page。简而言之,如果将内存划分为适当的大小(通常为2的指数,并且至少是CPU register大小的倍数),则会得到非常陡峭的optimizations,因为CPU只能以某些粒度。

由于所有这些,程序本身必须要求内核为其分配内存,以便程序可以使用它并确保它是唯一可以访问它的进程。

malloc()是执行此任务的标准函数调用。当您以一定长度调用malloc()时,系统将尝试查找未使用的系统内存的contiguous范围,并将其映射到进程的virtual memory空间中,存储您所请求的内存的地址和长度。

如果找不到足够的内存,则只返回NULL(0)-您可以在手册页中阅读:)

随后,当您调用free()时,它将在虚拟内存表中查找地址,检索您最初malloc()的长度,并告诉系统该进程不再需要该内存区域。

最后一点:segmentation fault通常是由不再分配的内存访问引起的,即使它曾经被分配。这就是为什么发明诸如RAII之类的C ++范例的原因-只是为了减少过早释放内存或根本不释放内存的可能性(即,使用一堆直到进程返回才分配的内存)。



有了以上知识,realloc()应该是小菜一碟。再次让我们看一下其手册页:


  realloc(ptr, size)函数尝试将ptr指向的分配大小更改为size,并返回ptr。如果没有足够的空间来扩展ptr指向的内存分配,则realloc()创建新的分配,复制ptr指向的尽可能多的旧数据,以适应新的分配,释放旧的分配,并返回指向分配的内存的指针。如果ptrNULL,则realloc()与对malloc()size字节调用相同。如果size为零而ptr不是NULL,则分配一个新的最小大小的对象,并释放原始对象。


这很长,但是基本上可以告诉您您需要知道的确切信息。

realloc()malloc()非常相似,您可以为它传递一个长度,但是您还可以传递一个以前的malloc()指针来调整其大小。

简而言之,您基本上是在扩展先前通过malloc()分配的内存区域。

混淆通常是由于realloc()并不总是扩展初始存储区域,而且,free()甚至会传递您传入的存储区域!

记住我上面关于连续内存的观点:如果您要求malloc()分配10个字节,而这10个字节恰好恰好恰好位于已经分配的其他两个内存区域之间,那么您想将这10个字节的区域调整为,例如20个字节-会发生什么?

由于内存区域必须是连续的,这意味着必须找到一个新的内存空间才能连续容纳所有20个字节!

在这种情况下,realloc()足以找到具有足够空间的新区域,从原始内存区域复制所有旧数据(由您提供的realloc()指向的指针),释放旧区域,然后返回新区域的地址。

这就是为什么必须始终存储realloc()的返回地址的原因:

char *ptr = malloc(100);
ptr = realloc(ptr, 400); // not guaranteed the first and
// second addresses will be the same!

关于c - 挣扎与malloc/realloc和结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40014006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com