動態內存管理—C語言通訊錄

目錄

一,動態內存函數的介紹

1.1 malloc和free

1.2 calloc

1.3 realloc

1.4C/C++程序的內存開辟

二,通訊錄管理系統


動態內存函數的介紹

malloc

free

calloc

realloc

一,動態內存函數的介紹

1.1 malloc和free

void* malloc ( size_t size );
這個函數向內存申請一塊連續可用的空間,并返回指向這塊空間的指針。
如果開辟成功,則返回一個指向開辟好空間的指針。
如果開辟失敗,則返回一個NULL 指針,因此 malloc的返回值一定要做檢查。
返回值的類型是 void* ,所以 malloc函數并不知道開辟空間的類型,具體在使用的時候使用者自己來決定。
如果參數 size 0 malloc的行為是標準是未定義的,取決于編譯器。
void free ( void* ptr );
free 函數用來釋放動態開辟的內存。
如果參數 ptr 指向的空間不是動態開辟的,那 free 函數的行為是未定義的。
如果參數 ptr NULL 指針,則函數什么事都不做。
可以看到,free之后將向內存申請的空間給釋放了,當然不要忘了將他設置為NULL防止野指針的使用,當然如果不釋放的話會出現內存泄漏的問題,我們的電腦把程序關了,就退出了,我們申請的空間也就被釋放的,但是有些服務器是一直不關的,那如果在使用時一直內存泄漏會出現問題的。

1.2 calloc

void* calloc ( size_t num , size_t size );
函數的功能是為 num 個大小為 size 的元素開辟一塊空間,并且把空間的每個字節初始化為 0
與函數 malloc 的區別只在于 calloc 會在返回地址之前把申請的空間的每個字節初始化為全 0

例如:

1.3 realloc

realloc 函數的出現讓動態內存管理更加靈活。
有時會我們發現過去申請的空間太小了,有時候我們又會覺得申請的空間過大了,那為了合理的時候內存,我們一定會對內存的大小做靈活的調整。那 realloc 函數就可以做到對動態開辟內存大小的調整。
void* realloc ( void* ptr , size_t size );
ptr 是要調整的內存地址
size 調整之后新大小
返回值為調整之后的內存起始位置。
這個函數調整原內存空間大小的基礎上,還會將原來內存中的數據移動到 的空間。
realloc 在調整內存空間的是存在兩種情況
情況 1 :原有空間之后有足夠大的空間
情況 2 :原有空間之后沒有足夠大的空間
情況 1
當是情況 1 的時候,要擴展內存就直接原有內存之后直接追加空間,原來空間的數據不發生變化。
情況 2
當是情況 2 的時候,原有空間之后沒有足夠多的空間時,擴展的方法是:在堆空間上另找一個合適大小的連續空間來使用。這樣函數返回的是一個新的內存地址。

將剛剛malloc的空間擴大了2唄,當然指針在給p1之前是需要判斷是否開辟成功的,如果沒有足夠的空間去開辟的話,realloc是會返回NULL指針的,如果用p1去接受,那么就會找不到原來的地址進而導致內存泄漏。

1.4C/C++程序的內存開辟

1. 棧區(stack):在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結
束時這些存儲單元自動被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是
分配的內存容量有限。 棧區主要存放運行函數而分配的局部變量、函數參數、返回數據、返
回地址等。
2. 堆區(heap):一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。分
配方式類似于鏈表。
3. 數據段(靜態區)(static)存放全局變量、靜態數據。程序結束后由系統釋放。
4. 代碼段:存放函數體(類成員函數和全局函數)的二進制代碼

二,通訊錄管理系統

頭文件:

contact.h

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
//通訊錄信息包含姓名,年齡,性別,電話,住址
typedef struct PeoInfo
{char name[20];int age;char sex[10];char tele[12];char addr[30];
}PeoInfo;
typedef struct Contact
{//每個人的信息PeoInfo* data;//當天通訊錄存儲的個數int count;//當前通訊錄的容量int capacity;
}Contact;//銷毀通訊錄
void DestoryContact(Contact* pc);
//初始化通訊錄
void InitContact(Contact* pc);//增加通訊錄信息
void AddContact(Contact* pc);//打印通訊錄的內容
void ShowContact(Contact* pc);
//刪除通訊錄的內容
void DelContact(Contact* pc);
//查找通訊錄的信息
void SearchContact(Contact* pc);
//修改通訊錄的信息
void ModifyContact(Contact* pc);
//排序通訊錄的內容
void SortContact(Contact* pc);
contact.c文件
#include"contact.h"//初始化通訊錄
void InitContact(Contact* pc)
{//斷言,pc不為空assert(pc);//初始時我們給通訊錄兩個大小的空間Contact* temp = (PeoInfo*)calloc(2, sizeof(PeoInfo));//如果開辟成功這將if (temp){pc->data = temp;pc->capacity = 2;pc->count = 0;}
}//檢測通訊錄容量
void Checkcapacity(Contact* pc)
{//如果當前容量等于我們的存放信息的個數那么我們就擴容if (pc->capacity == pc->count){Contact* temp = (Contact*)realloc(pc->data, sizeof(PeoInfo) * 4);if (temp){pc = temp;//每次增容成功會都要增加capacity的值pc->capacity = pc->capacity + 4;printf("增容成功\n");}}
}//增加聯系人
void AddContact(Contact* pc)
{assert(pc);//判斷通訊錄是否已滿Checkcapacity(pc);//添加信息printf("請輸入姓名:>");scanf("%s", pc->data[pc->count].name);printf("請輸入年齡:>");scanf("%d", &pc->data[pc->count].age);printf("請輸入性別:>");scanf("%s", pc->data[pc->count].sex);printf("請輸入電話:>");scanf("%s", pc->data[pc->count].tele);printf("請輸入住址:>");scanf("%s", pc->data[pc->count].addr);//每次添加聯系人之后要將count+1pc->count++;printf("添加成功\n");
}//銷毀通訊錄
void DestoryContact(Contact* pc)
{//釋放我們申請的空間free(pc->data);pc->data = NULL;
}//展示通訊錄的信息
void ShowContact(Contact* pc)
{assert(pc);int i = 0;printf("%-10s%-10s%-10s%-12s%-10s\n", "姓名", "年齡", "性別", "電話", "住址");for (i = 0; i < pc->count; i++){printf("%-10s%-10d%-10s%-20s%-15s", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);printf("\n");}}//查找通訊錄里面是否有這個 不考慮重名問題
int find_by_name(Contact* pc, char name[])
{assert(pc);int i = 0;for (i = 0; i < pc->count; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}//刪除通訊錄中某個人的信息
void DelContact(Contact* pc)
{assert(pc);printf("請輸入要刪除人的姓名:>");char name[20] = { 0 };//如果通訊錄中沒有信息if (pc->count == 0){printf("通訊錄中沒有信息可刪除\n");return;}scanf("%s", name);//查找信息int pos = find_by_name(pc, name);if (pos == -1){printf("要刪除的人不存在\n");return;}//刪除信息int i = 0;for (i = pos; i <= pc->count - 1; i++){pc->data[pos] = pc->data[pos + 1];}pc->count--;printf("刪除成功\n");
}//查找通訊錄中的某個人
void SearchContact(Contact* pc)
{assert(pc);if (pc->count == 0){printf("通訊錄中沒有信息可刪除\n");return;}char name[20] = { 0 };printf("請輸入你要查找人的名字:>");scanf("%s", name);int pos = find_by_name(pc, name);if (pos == -1){printf("要刪除的人不存在\n");return;}printf("要查找人的信息如下:>\n");printf("%-10s%-10s%-10s%-12s%-10s\n", "姓名", "年齡", "性別", "電話", "住址");printf("%-10s%-10d%-10s%-20s%-15s", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);printf("\n");
}//修改通訊錄中某個人信息
void ModifyContact(Contact* pc)
{assert(pc);if (pc->count == 0){printf("通訊錄中沒有信息可修改\n");return;}char name[20] = { 0 };//查找printf("請輸入你要修改信息人的名子:>");scanf("%s", name);int pos = find_by_name(pc, name);if (pos == -1){printf("要修改的人的信息不存在\n");return;}//修改printf("請輸入你要修改的內容:\n");printf("請輸入姓名:>");scanf("%s", pc->data[pos].name);printf("請輸入年齡:>");scanf("%d", &pc->data[pos].age);printf("請輸入性別:>");scanf("%s", pc->data[pos].sex);printf("請輸入電話:>");scanf("%s", pc->data[pos].tele);printf("請輸入住址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}//給qsort函數的比較函數
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
//排序我們的通訊錄,按照名字排序
void SortContact(Contact* pc)
{assert(pc);qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}
test.c
#include "contact.h"void menu()
{printf("**************************************\n");printf("**************************************\n");printf("*******  1.add     2.Del    **********\n");printf("*******  3.search  4.modify **********\n");printf("*******  5.show    6.sort   **********\n");printf("*******  0.exit             **********\n");printf("**************************************\n");printf("**************************************\n");
}
int main()
{int input = 0;Contact con;InitContact(&con);do{   //打印菜單做提示menu();printf("請選擇:>");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:SearchContact(&con);break;case 4:ModifyContact(&con);break;case 5:ShowContact(&con);break;case 6:SortContact(&con);break;case 0:printf("退出程序\n");DestoryContact(&con);break;default:printf("選擇錯誤請重新選擇:>");break;}} while (input);return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18101.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18101.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18101.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

回文鏈表(快慢指針解法之在推進過程中反轉)

歸納編程學習的感悟&#xff0c; 記錄奮斗路上的點滴&#xff0c; 希望能幫到一樣刻苦的你&#xff01; 如有不足歡迎指正&#xff01; 共同學習交流&#xff01; &#x1f30e;歡迎各位→點贊 &#x1f44d; 收藏? 留言?&#x1f4dd;抱怨深處黑暗&#xff0c;不如提燈前行…

進程間通信IPC機制

進程間通信&#xff08;IPC&#xff0c;InterProcess Communication&#xff09;是指在不同進程之間傳播或交換信息。IPC機制有多種方式&#xff0c;每種方式都有其特定的工作原理、應用場景以及優缺點。以下是對幾種主要IPC方式的詳細解釋&#xff1a; 管道&#xff08;Pipe&a…

數據結構算法題day04

數據結構算法題day04 題目分析算法思想代碼完整運行代碼如下&#xff1a; 題目 對長度為n的順序表L&#xff0c;編寫一個時間復雜度為O(n)、空間復雜度為O(1)的算法 該算法刪除線性表中所有值為X的數據元素。分析 O(n) -> 掃描一次順序表 O(1) -> 申請常數個輔助空間 1…

代碼隨想錄算法訓練營day14|二叉樹的遞歸遍歷、二叉樹的迭代遍歷、二叉樹的統一迭代法

二叉樹的遞歸遍歷 首先需要明確的一點是&#xff0c;前序中序和后序在二叉樹的遞歸遍歷中的區別僅在于遞歸函數中操作的順序&#xff0c;前序是在遍歷一個節點的左右子樹前進行操作&#xff0c;中序是在遍歷一個節點的左子樹后進行操作再遍歷右子樹&#xff0c;而后序是在遍歷…

C++算術運算和自增自減運算

一 引言 表示運算的符號稱為運算符。 算術運算&#xff1b; 比較運算&#xff1b; 邏輯運算&#xff1b; 位運算&#xff1b; 1 算術運算 算術運算包括加、減、乘、除、乘方、指數、對數、三角函數、求余函數&#xff0c;這些都是算術運算。 C中用、-、*、/、%分別表示加、減…

【AI】AI框架項目OpenWebUI如何追加模型

【背景】 openWebUI是一個非常好用的AI框架項目&#xff0c;既可以用API形式連接各類外部AI模型&#xff0c;也可以直接連接服務器硬盤上部署的離線大模型。 簡單來說&#xff0c;OpenWebUI可以用來方便地把你的本地模型變為可供所有內網人員使用的SAAS服務站點&#xff0c;并…

《當微服務遇上Ribbon:一場負載均衡的華麗舞會》

在微服務的廚房里&#xff0c;如何確保每一道服務都恰到好處&#xff1f;揭秘Spring Cloud Ribbon如何像大廚一樣精心調配資源&#xff0c;讓負載均衡變得像烹飪藝術一樣簡單&#xff01; 文章目錄 Spring Cloud Ribbon 詳解1. 引言微服務架構中的負載均衡需求Spring Cloud Rib…

【算法實戰】每日一題:設計一個算法,用最少數量的矩形覆蓋一系列寬度為d、高度為w的矩形,且使用矩形不能超出邊界

題目 設計一個算法&#xff0c;用最少數量的矩形覆蓋一系列寬度為d、高度為w的矩形建筑物側墻&#xff0c;且矩形不能超出邊界。 核心思路 考慮這種結構 前面遞增后面一個與前面的某個高度一致&#xff0c;這時候考慮最下面的覆蓋&#xff08;即都是從最下面向上覆蓋&#…

redis數據類型set,zset

華子目錄 Set結構圖相關命令sdiff key1 [key2]sdiffstore destination key1 [key2...]sinter key1 [key2...]sinterstore destination key1 [key2...]sunion key1 [key2...]sunionstore destination key1 [key2...]smove source destination memberspop key [count]sscan key c…

Java GC問題排查的一些個人總結和問題復盤

個人博客 Java GC問題排查的一些個人總結和問題復盤 | iwts’s blog 是否存在GC問題判斷指標 有的比較明顯&#xff0c;比如發布上線后內存直接就起飛了&#xff0c;這種也是比較好排查的&#xff0c;也是最多的。如果單純從優化角度&#xff0c;看當前應用是否需要優化&…

探索旅行的優惠之選,千益暢行旅游卡讓旅程更省心省力!

在旅行的道路上&#xff0c;一張旅游卡往往能為您帶來意想不到的便利與優惠。那么&#xff0c;對于千益暢行旅游卡&#xff0c;您是否好奇如何輕松擁有它呢&#xff1f; 首先&#xff0c;千益暢行旅游卡作為旅行者的貼心伴侶&#xff0c;為您提供了多樣化的獲取渠道。您可以通…

Unity實現首行縮進兩個字符

效果 在Unity中如果想實現首行縮進兩個字符&#xff0c;你會發現按空格是沒法實現的。 實現原理&#xff1a;用空白的透明的字替代原來的位置。 代碼&#xff1a; <color#FFFFFF00>XXX</color> 趕緊去試試吧&#xff01;

備戰秋招—模擬版圖面試題來了

隨著暑期的腳步逐漸臨近&#xff0c;電子工程和集成電路設計領域的畢業生們&#xff0c;也將迎來了另一個求職的黃金期——秋招。我們總說機會是留給有準備的人。對于有志于投身于模擬版圖設計的學子們來說&#xff0c;為了在眾多求職者中脫穎而出&#xff0c;充分備戰模擬版圖…

C# 工商銀行缺少infosecapiLib.infosec

搜索Tlbimp.exe 這里使用4.8.1下的處理&#xff0c;以管理員身份打開powershell cd "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8.1 Tools".\TlbImp.exe "G:\CSharp\icbc-api-sdk-cop-c#\sdk-cop\sdk-cop\dll\infosecapi.dll" …

PCIe協議之-DLLP詳解

?前言&#xff1a; &#x1f31f;數據鏈路層的功能 數據鏈路層將從物理層中獲得報文&#xff0c; 并將其傳遞給事務層&#xff1b; 同時接收事務層的報文&#xff0c; 并將其轉發到物理層; 核心的功能有以下三點 1.保證TLP在 PCIe 鏈路中的正確傳遞; 2.數據鏈路層使用了容錯…

頁面導出PDF,非可視區域如何解決

const exportToPDF () > {const element document.getElementById(chart-container);if (!element) return;const originalScrollHeight element.scrollHeight;// 臨時解除滾動條限制&#xff0c;確保所有內容都可見element.style.height ${originalScrollHeight}px;// …

殺死那個進程

一、場景 eclipse在啟動tomcat時&#xff0c;出現端口被占用的情況。我尋思著“任務管理器”沒出現相應程序在跑啊。 1.1問題&#xff1a;端口和進程的關系 端口和進程之間存在著一種關系&#xff0c;端口是一個邏輯概念&#xff0c;它用于標識網絡通信中的一個終點&#xff0…

SEC突發:以太坊ETF大概率獲批

美國證監會大概率批準以太坊現貨ETF。 5月20日&#xff0c;據外媒CoinDesk報道&#xff0c;知情人士透露&#xff0c;美國SEC周一要求證券交易所更新以太坊現貨ETF的19b-4備案文件。19b-4備案文件是一種表格&#xff0c;用于向SEC通報允許基金在交易所交易的規則變更。 三位消息…

利用cherry pick巧妙地將某次提交單獨合并到其他分支

0. 引言 最近在進行系統的多版本并行開發&#xff0c;涉及一些共有基礎功能提交時就遇到了麻煩&#xff0c;一份代碼需要向多個版本分支進行同步&#xff0c;以保證多版本都能有更新該基礎功能。 多次對比提交的方式顯然會帶來巨大的工作量。但實際上我們可以通過git的cherry…

「Python Socket超能力:網絡世界的隱形斗篷!」

Hi&#xff0c;我是阿佑&#xff0c;今天將帶領大家揭開Python Socket編程的神秘面紗&#xff0c;賦予我們的網絡應用隱形斗篷般的超能力&#xff01; 深入探討Socket編程的革命性力量&#xff0c;教你如何用Python的Socket模塊來構建強大的網絡應用。從簡單的HTTP服務器到復雜…