จะแก้ไขตัวระบุการประกาศที่คาดหวัง realloc หรือข้อผิดพลาด '…' before 'sizeof' ได้อย่างไร?

Aug 15 2020

ฉันได้รับข้อผิดพลาดต่อไปนี้ด้านล่างหลังจากโทร realloc

void* realloc(sizeof(char)100);

ข้อผิดพลาด:

linex.c: 23: 16: ข้อผิดพลาด: ตัวระบุการประกาศที่คาดไว้หรือ "... " ก่อน "sizeof"

กรุณาช่วย. ขอขอบคุณ. :)

คำตอบ

1 RobertSsupportsMonicaCellio Aug 15 2020 at 15:42
void realloc(sizeof(char)100);

สมมติว่าคุณหมายถึงการเรียกใช้realloc()ฟังก์ชันมาตรฐาน(ไม่ใช่การประกาศกำหนดเองrealloc()) และคุณต้องการปรับขนาดหน่วยความจำรหัสนี้ไม่ถูกต้องเกี่ยวกับสามจุด

1.

realloc() ต้องการตัวชี้ไปยังหน่วยความจำที่จัดสรรโดยการจัดการหน่วยความจำและยังไม่ได้ปลดปล่อยเป็นอาร์กิวเมนต์แรก

นี่คือต้นแบบ / การประกาศสำหรับrealloc()ฟังก์ชันมาตรฐาน:

void *realloc( void *ptr, size_t new_size );

การrealloc()โทรของคุณละเว้นอาร์กิวเมนต์ตัวชี้นี้

2.

อย่าระบุประเภทการส่งคืน (ที่นี่void *) เมื่อคุณต้องการเรียกใช้ฟังก์ชัน ด้วยวิธีนี้คุณจะพยายามประกาศฟังก์ชันใหม่realloc()ไม่ใช่การโทร

หากคุณพยายามแคสต์ที่นี่ก็ถือว่าผิดเช่นกัน (void *)สำหรับนักแสดงนัยคุณจะต้องล้อมรอบประเภทที่จะหล่อไปด้วยวงเล็บเช่น

โปรดทราบว่าในทั้งสองกรณีการร่ายซ้ำซ้อน ด้วยมุมมองเกี่ยวกับนักแสดงประเภทรีเทิร์นดูที่:

  • ฉันส่งผลลัพธ์ของ malloc หรือไม่

3.

ที่โต้แย้งขนาดที่คุณจำเป็นต้อง*ดำเนินการระหว่างและsizeof(char)100


ใช้:

realloc( ptr, sizeof(char) * 100 );

โปรดทราบว่าคุณควรตรวจสอบค่าส่งคืนของฟังก์ชันการจัดการหน่วยความจำเสมอว่ามีข้อผิดพลาดเกิดขึ้นหรือไม่:

char * ptr2 = realloc( ptr1, sizeof(char) * 100);
if ( ptr2 == NULL )
{
    fputs("Error at resizing the allocated memory!\n", stderr);
    // error routine.
}

เช่นเดียวกับคุณเสมอควรทำสำหรับmalloc():

char * ptr1 = malloc( sizeof(char) * 50);
if ( ptr1 == NULL )
{
    fputs("Error at memory allocation!\n", stderr);
    // error routine.
}

บทเรียนขั้นสูง (คุณไม่จำเป็นต้องเข้าใจในตอนนี้):

โปรดทราบว่าในกรณีนี้realloc()ฉันใช้ตัวชี้อื่นเพื่อจับค่าส่งคืนของrealloc().

เนื่องจากrealloc()อาจส่งคืนตัวชี้เดียวกันหรือไม่ก็ได้เป็นอาร์กิวเมนต์

น่าเสียดายที่การปฏิบัติร่วมกัน realloc()แต่ไม่ดีคือการโอนตัวชี้เป็นอาร์กิวเมนต์เป็นครั้งแรกโดยค่าตอบแทนของ

สิ่งนี้อันตรายเนื่องจากการอ้างอิงไปยังหน่วยความจำที่จัดสรรก่อนอาจสูญหายได้หากrealloc()จัดสรรหน่วยความจำ "ทดแทน" อื่น แต่ไม่ได้ลบออก

ที่เกี่ยวข้อง:

  • การเขียนโค้ดที่ดีควรกำหนดที่อยู่ที่ส่งคืนโดย realloc () ให้กับตัวชี้เดียวกันหรือไม่
  • https://stackoverflow.com/a/25435175/12139179
  • realloc () จะจัดสรรหน่วยความจำใหม่ได้อย่างไร?
1 EricPostpischil Aug 15 2020 at 17:35

void* realloc(sizeof(char)*100); เป็นความเข้าใจผิดในการประกาศฟังก์ชันและเรียกมัน

เมื่อเราประกาศvoid *realloc(void *, size_t);ฟังก์ชั่นที่เราพูดในสิ่งที่ชนิดของผลตอบแทนที่เป็นและประเภทสิ่งพารามิเตอร์ที่มีในขณะที่ void *realloc(void *pointer, size_t size);นอกจากนี้เรายังอาจให้ชื่อตัวยึดสำหรับพารามิเตอร์ที่เป็นรายละเอียดที่เป็นประโยชน์เช่นเดียวกับใน (ต้องระบุชื่อพารามิเตอร์เมื่อกำหนดฟังก์ชันอย่างสมบูรณ์)

เมื่อเราเรียกใช้ฟังก์ชันเราจะไม่ตั้งชื่อประเภทสำหรับค่าส่งคืนหรือพารามิเตอร์ เราเพียงแค่ให้นิพจน์ที่ให้ค่าอาร์กิวเมนต์เช่นเดียวกับในNewPointer = realloc(OldPointer, 100 * sizeof *NewPointer);.

บางครั้งชื่อประเภทอาจปรากฏในหรือใกล้กับการเรียกใช้ฟังก์ชัน แต่ชื่อประเภทนี้อาจเกิดขึ้นโดยบังเอิญและไม่ได้เป็นส่วนหนึ่งของการเรียกฟังก์ชันโดยตรง ตัวอย่าง ได้แก่ :

  • char *NewPointer = realloc(OldPointer, 100 * sizeof *NewPointer);: รหัสนี้มีเพราะมันประกาศและกำหนดchar * NewPointerจากนั้นNewPointerจะเริ่มต้นด้วยการreallocโทร
  • NewPointer = (char *) realloc(OldPointer, 100 * sizeof *NewPointer);: โค้ดนี้มี(char *)การร่ายเพื่อแปลงค่าที่ส่งคืนreallocเป็นชนิดตัวชี้เฉพาะ สิ่งนี้ไม่จำเป็นใน C.
  • NewPointer = realloc(OldPointer, 100 * sizeof(char));: รหัสนี้char *เป็นตัวถูกดำเนินการsizeofในการคำนวณพื้นที่ที่ต้องการ สิ่งนี้ไม่จำเป็นเนื่องจากสามารถใช้ขนาดได้sizeof *NewPointerและโดยทั่วไปแล้วจะดีกว่าเนื่องจากจะปรับตามการเปลี่ยนแปลงโดยอัตโนมัติในการประกาศNewPointerลดความเป็นไปได้ที่อาจเกิดข้อบกพร่องโดยการเปลี่ยนประเภทในการประกาศNewPointerแต่มองข้ามsizeofนิพจน์