هل هناك حاجة لتدمير char * = "string" أو char * = new char[6]؟

StackOverflow https://stackoverflow.com/questions/51592

  •  09-06-2019
  •  | 
  •  

سؤال

أفترض ذلك char* = "string" هو نفسه ل char* = new char[6].أعتقد أن هذه السلاسل يتم إنشاؤها على الكومة بدلاً من المكدس.فهل أحتاج إلى تدميرهم أو تحرير ذاكرتهم عندما أنتهي من استخدامها أم يتم تدميرهم بأنفسهم؟

هل كانت مفيدة؟

المحلول

لا.ما عليك سوى تحرير السلاسل يدويًا عندما تقوم بتخصيص الذاكرة يدويًا بنفسك باستخدام ملف malloc وظيفة (في C) أو new المشغل (في C++).إذا كنت لا تستخدم malloc أو new, ، ثم char* أو سيتم إنشاء سلسلة على المكدس أو كثابت وقت الترجمة.

نصائح أخرى

لا.عندما تقول:

const char* c = "Hello World!";

أنت تقوم بتعيين c لثابت سلسلة "موجود مسبقًا" وهو ليس مثل:

char* c = new char[6];

فقط في الحالة الأخيرة تقوم بتخصيص الذاكرة على الكومة.لذا يمكنك استدعاء الحذف عند الانتهاء.

أفترض عندما أفعل char* = "string" إنه نفس الشيء char* = new char[6].

لا.ما يفعله الأول هو إنشاء ثابت.تعديله هو سلوك غير محدد.ولكن للإجابة على سؤالك؛لا، ليس عليك تدميرهم.ومجرد ملاحظة، استخدم دائما std::string متى أمكن.

اسم اللعبة هو "تدمير فقط ما قمت بإنشائه".وهنا الأزواج:

  1. malloc/free
  2. calloc/free
  3. new/delete
  4. new []/delete []

منذ أن قمت بإنشاء السلسلة الثانية باستخدام new [], ، يقع على عاتقك مسؤولية تدميرها delete [].يتصل delete [] string2 عندما تنجز.

الآن، إذا كانت التعليمات البرمجية الخاصة بك معقدة بدرجة كافية وتجعل تتبع عمليات الحذف أمرًا صعبًا، ففكر في استخدام المؤشرات المحددة النطاق أو المؤشرات التلقائية.ال boost::scoped_ptr يعد الفصل من مكتبة Boost مكانًا جيدًا للبدء.أنظر أيضاً في رايي لغة، أشياء مفيدة جدًا ومفيدة.

انهم ليسوا نفس الشيء.المثال الأول الخاص بك عبارة عن سلسلة ثابتة، لذلك لم يتم تخصيصها بالتأكيد من الكومة.المثال الثاني هو تخصيص ذاكرة وقت التشغيل مكونة من 6 أحرف، ويأتي ذلك من الكومة.لا تريد حذف المثال الأول، ولكن عليك القيام بذلك delete [] المثال الثاني الخاص بك.

أنت لا تعرف مكان تخزين السلسلة الحرفية.قد تكون أيضًا ذاكرة للقراءة فقط، لذلك يجب أن يقرأ الكود الخاص بك:

const char* c = "string";

و أ جديد ينبغي أن تكون مجموعة شار يمسحd تمامًا مثل أي منطقة ذاكرة أخرى مخصصة ديناميكيًا.

new هو دائمًا تخصيص بينما تحديد سلسلة مضمنة يؤدي في الواقع إلى تضمين البيانات في البرنامج نفسه ولا يمكن تغييره (بعض المترجمين يسمحون بذلك عن طريق خدعة ذكية، لا تهتم).

تقوم بعض المترجمات بكتابة سلاسل مضمنة بحيث لا يمكنك تعديل المخزن المؤقت.

char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted

دعونا نرى ما يفعله نظام Linux الخليجي 4.8 x86-64

برنامج:

#include <cstdio>
int main() {
    const char *s = "abc";
    char *sn = new char[4];
    sn[3] = '\0';
    std::printf("%s\n", s);
    std::printf("%s\n", sn);
}

تجميع وتفكيك:

g++ -ggdb -std=c++98 a.cpp
objdump -CSr a.o

يحتوي الإخراج على:

  const char *s = "abc";
 8:   48 c7 45 f0 00 00 00    movq   $0x0,-0x10(%rbp)
 f:   00 
                     c: R_X86_64_32S .rodata
  char *sn = new char[4];
10:   bf 04 00 00 00          mov    $0x4,%edi
15:   e8 00 00 00 00          callq  1a <main+0x1a>
                        16: R_X86_64_PC32       operator new[](unsigned long)-0x4
1a:   48 89 45 f8             mov    %rax,-0x8(%rbp)

تفسير:

  • char *s = "abc" يدخل .rodata.لذلك لا يمكن free ذلك بأي شكل من الأشكال.
  • char *sn = new char[4]; يأتي من إخراج operator new[].لذلك يجب عليك تحريره عندما تستطيع.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top