วิธีใช้ realloc ใน C [ซ้ำ]

Nov 25 2020

ฉันกำลังพยายามจัดสรรหน่วยความจำใหม่โดยใช้ฟังก์ชัน realloc ฉันเห็นว่าคุณต้องใช้ malloc มาก่อน แต่ฉันไม่เข้าใจว่าคุณต้องใช้หรือไม่เพราะสมมติว่าฉันกำลังสร้างสตริงต่อไปนี้:

char string[] =  "fun";

ฟังก์ชัน realloc จะใช้งานได้หรือไม่ถ้าฉันพยายามเพิ่มพื้นที่มากขึ้น

นั่นทำให้ฉันมาถึงคำถามของฉันฉันกำลังพยายามเพิ่มตัวอักษรหนึ่งตัวที่ท้ายสตริงสมมติว่า 'p' แต่ด้วยเหตุผลบางอย่างโปรแกรมจะบดขยี้ในบรรทัด realloc ทุกครั้งที่เรียกใช้

นี่คือรหัสเต็มของฉัน:

int main()
{
char string[] =  "fun" ;
str_func(string);
printf("%s", string);
return 0;
} 

void str_func(char* str)
{
str = (char*)realloc(str, strlen(str) + 2);
strcat(str, "p");
}

ฉันยังลองสร้างตัวชี้เป็น 'สตริง' และส่งตัวชี้ซึ่งได้ผลลัพธ์เช่นเดียวกัน

คำตอบ

1 Lundin Nov 25 2020 at 19:32

ฟังก์ชัน realloc จะใช้งานได้หรือไม่ถ้าฉันพยายามเพิ่มพื้นที่มากขึ้น

ไม่เนื่องจากอาร์เรย์นั้นไม่ได้รับการจัดสรรบนฮีป - ในกรณีของคุณมีโอกาสมากที่จะจัดสรรบนสแตกและไม่สามารถปรับขนาดได้ ใส่เพียงแค่: reallocไม่รู้จักตัวชี้และไม่รู้ว่าจะทำอย่างไรกับมัน แต่พยายามทำอะไรบางอย่างต่อไปดังนั้นจึงเกิดความผิดพลาด

คุณสามารถเรียกreallocใช้ตัวชี้ที่ถูกส่งไปก่อนหน้านี้mallocหรือบนตัวชี้ค่าว่างเท่านั้น นั่นเป็นเพียงวิธีการทำงานของฟังก์ชันเหล่านี้

สำหรับรายละเอียดโปรดดูสิ่งที่ได้รับการจัดสรรบนสแต็กและฮีป .

1 Useless Nov 25 2020 at 19:58

ฉันเห็นว่าคุณต้องใช้ malloc มาก่อน แต่ฉันไม่เข้าใจว่าคุณต้องใช้หรือไม่

หากคุณจำเป็นต้องใช้mallocก่อนที่คุณจะสามารถทำreallocบางสิ่งได้ตามความหมายคุณจะต้องreallocจัดสรรเฉพาะสิ่งที่มีอยู่เดิมmallocเท่านั้น

คุณกำลังพยายามหาช่องว่างระหว่าง "ความต้องการ" และ "ต้อง" ที่ไม่มีอยู่จริง

... ด้วยเหตุผลบางประการโปรแกรมจึงบดขยี้การจัดสรรใหม่

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

โปรแกรมน่าจะมีลักษณะดังนี้

int main()
{
  /* array is an automatic local variable. It wasn't dynamically allocated
     in the first place, so can't be dynamically re-allocated either.
     You cannot (and don't need to) free it either, it just goes out of scope
     like any other automatic variable.
  */
  char array[] = "fun";

  /* you need to use malloc (or one of the other dynamic allocation functions)
     before you can realloc, as you said yourself */
  char *dynamic = malloc(1+strlen(array));
  memcpy(dynamic, array, 1+strlen(array));

  /* realloc can move your data, so you must use the returned address */
  dynamic = str_func(dynamic);
  printf("old:'%s', new:'%s'\n", array, dynamic);

  /* not really essential since the program is about to exit anyway */
  free(dynamic);
} 

char* str_func(char* str)
{
  char* newstr = realloc(str, strlen(str) + 2);
  if (newstr) {
    strcat(newstr, "p");
    return newstr;
  } else {
    /* we failed to make str larger, but it is still there and should be freed */
    return str;
  }
}

สภาพเดิมของคุณไม่ถูกต้อง: ตัวชี้ส่งผ่านไปยัง realloc

... จะต้องได้รับการจัดสรรโดยก่อนหน้านี้malloc(), calloc()หรือrealloc()และยังไม่เป็นอิสระที่มีการเรียกร้องให้ฟรีหรือ realloc

[OR] ถ้า PTR malloc(new_size)เป็นโมฆะพฤติกรรมเป็นเช่นเดียวกับการโทร

paxdiablo Nov 25 2020 at 19:31

reallocฟังก์ชั่นใช้งานได้เฉพาะกับสิ่งที่ถูกสร้างขึ้นครั้งแรกกับกลุ่มเล็ก ๆ ของฟังก์ชั่นการจัดสรร (เช่นmalloc, callocหรือreallocตัวเอง) หรือตัวชี้โมฆะ เนื่องจากstringไม่มีสิ่งเหล่านี้แสดงว่ารหัสของคุณจึงไม่ได้กำหนดไว้อย่างชัดเจน