การจัดสรรหน่วยความจำแบบไดนามิกสำหรับโหนดในรายการที่เชื่อมโยง

Aug 20 2020

เหตุใดเมื่อฉันต้องประกาศตัวชี้ไปยังโหนด (ส่วนหัว) ฉันจึงต้องจัดสรรหน่วยความจำด้วยmallocหรือcallocเพื่อสิ่งนั้น ผมเห็นว่ารหัสที่สร้างรายการ (ไม่ได้นำเข้าที่นี่) node *headยังทำงานได้ดีโดยไม่ต้องจัดสรรหน่วยความจำสำหรับมันและเพียงแค่ประกาศ

typedef struct str_node{
    int data;
    struct str_node *next;
}node;

int main(){

    node *head;

    head = (node*) malloc(sizeof(node));
    head = NULL;

แล้วทำไมเมื่อฉันจัดสรรหน่วยความจำเหมือนข้างบนฉันต้องเขียน(node*)? มันไม่ได้ถูกจัดสรรให้กับโหนดโครงสร้างเนื่องจากฉันกำลังทำอยู่หรือไม่? ความหมายของรหัสบรรทัดนั้นคืออะไร? ยิ่งไปกว่านั้นเมื่อฉันเขียนhead = NULLฉันตั้งค่าที่อยู่ของหัวตัวชี้เป็น NULL หรืออะไร?

คำตอบ

2 VladfromMoscow Aug 19 2020 at 23:35

ข้อมูลโค้ดนี้

node *head;

head = (node*) malloc(sizeof(node));
head = NULL;

ทำให้หน่วยความจำรั่ว

ในตอนแรกหน่วยความจำสำหรับอ็อบเจ็กต์ประเภทnodeถูกจัดสรรและกำหนดแอดเดรสให้กับตัวชี้head

head = (node*) malloc(sizeof(node));

จากนั้นค่าของตัวชี้จะถูกเขียนทับในทันที

head = NULL;

เป็นผลให้ที่อยู่ของหน่วยความจำที่จัดสรรหายไปและไม่สามารถปลดปล่อยหน่วยความจำที่จัดสรรได้

ข้อมูลโค้ดไม่สมเหตุสมผล มันจะเพียงพอสำหรับการเขียน

node *head = NULL;

ในกรณีนี้คุณจะมีรายการว่างในตอนแรก

แล้วทำไมเมื่อฉันจัดสรรหน่วยความจำเหมือนข้างบนฉันต้องเขียน (โหนด *)?

ฟังก์ชั่นกลับชี้ประเภทที่malloc สามารถกำหนดvoid *ตัวชี้ประเภทvoid *ให้กับตัวชี้ของประเภทวัตถุอื่น ๆ ได้ ดังนั้นใน C การหล่อจึงซ้ำซ้อน

ใน C ++ คุณได้กำหนดตัวชี้ประเภทvoid *ไปยังประเภทของตัวชี้วัตถุที่กำหนดตัวชี้ประเภทvoid *ไว้อย่างชัดเจน

ยิ่งไปกว่านั้นเมื่อฉันเขียน head = NULL ฉันตั้งที่อยู่ของหัวพอยน์เตอร์เป็น NULL หรืออะไร?

คุณไม่ได้ตั้งค่าที่อยู่ของตัวชี้เอง ตัวชี้ถูกจัดสรรโดยคอมไพลเลอร์และมีระยะเวลาการจัดเก็บอัตโนมัติ คุณตั้งค่าของตัวแปรheadที่มีชนิดnode *เป็น NULL

2 rici Aug 19 2020 at 23:43

ใน C พอยน์เตอร์คือค่าเช่นเดียวกับจำนวนเต็ม เมื่อคุณเขียน:

int a;
a = 3;

คุณเก็บค่า 3 aเข้าไปในตัวแปร

เมื่อคุณเขียน:

int* p;
p = NULL;

คุณเก็บค่าลงในตัวแปรNULL ไม่มีอะไรพิเศษเกี่ยวกับพอยน์เตอร์ การมอบหมายงานไม่ได้ขึ้นอยู่กับคุณค่าของสิ่งใด ๆ นั่นคือสิ่งที่อาจชี้หรือไม่ได้ (ในกรณีนี้มันไม่ได้ชี้ไปที่อะไรเลย แต่ไม่เกี่ยวข้อง)pp

mallocส่งกลับตัวชี้ไปยังพื้นที่หน่วยความจำซึ่งตามที่กล่าวไว้ข้างต้นคือค่า ตัวชี้ไม่มีข้อมูลเมตาที่แท้จริง mallocไม่ต้องการข้อมูลใด ๆ ที่เกินขนาดของพื้นที่หน่วยความจำ ใน particuar ไม่ทราบ (หรือสนใจ) ว่าจะใช้พื้นที่หน่วยความจำเพื่ออะไร เมื่อสร้างมูลค่าแล้วคุณสามารถจัดการกับค่านั้นได้ตามที่เห็นสมควรตัวอย่างเช่น

int* p;
p = malloc(sizeof *p);

เนื่องจากpมีการประกาศเป็นตัวชี้ไปยัง an intจึงคาดว่าหน่วยความจำที่ชี้ไปpสามารถถือintไฟล์. (ยังทำไม่ได้ แต่ทำได้) แต่คุณสามารถส่งผ่านตัวชี้ (เป็นค่า) ได้โดยไม่ต้องมีผลกับจำนวนเต็ม (ถ้ามี) ที่เก็บไว้ในหน่วยความจำที่ชี้ไป ตัวอย่างเช่น after

int* q = p;

qและpชี้ไปที่หน่วยความจำเดียวกัน

หากคุณพบความสับสนนี้อาจเป็นเพราะคุณคาดหวังว่าตัวชี้จะเป็นอย่างอื่นที่ไม่ใช่ค่าธรรมดา อย่างไรก็ตามค่าเหล่านี้เป็นค่านิยมที่เรียบง่ายและคุณต้องมีแบบจำลองทางจิตใจซึ่งอยู่บนพื้นฐานของความเป็นจริงง่ายๆนั้น