سؤال

هل هناك دعوة يمكنني جعل لnew أن يكون ذلك الصفر من الذاكرة مثل calloc؟

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

المحلول

وعلى عكس ما يقول البعض في إجاباتهم، و<م> هو ممكن.

char * c = new char[N]();

هل الصفر تهيئة جميع الشخصيات (في الواقع، انه دعا قيمة التهيئة، ولكن قيمة التهيئة ستكون الصفر التهيئة لجميع أعضائها من مجموعة من نوع العددية). إذا كان هذا ما كنت بعد.

وورث أن نلاحظ أنه يعمل أيضا ل(صفائف) الطبقة أنواع من دون أعلن المستخدم المنشئ في هذه الحالة أي عضو منهم هو قيمة تمت تهيئته:

struct T { int a; };
T *t = new T[1]();
assert(t[0].a == 0);
delete[] t;

وانها ليست بعض تمديد أو شيء من هذا. عملت وتصرفت بنفس الطريقة في C ++ 98 أيضا. هناك فقط كان يسمى التهيئة الافتراضية بدلا من التهيئة القيمة. صفر التهيئة، ومع ذلك، يتم في كلتا الحالتين لسكالارس أو صفائف العددية أو POD الأنواع.

نصائح أخرى

لا ولكن من السهل نسبيا لإنشاء الإصدار الجديد الذي يتصرف مثل calloc. يمكن أن يتم ذلك بنفس الطريقة التي يتم بها تنفيذ النسخة عدم رمي جديدة.

وSomeFile.h

struct zeromemory_t{};
extern const zeromemory_t zeromemory;
void* __cdcel operator new(size_t cbSize, const zeromemory_t&);

وSomeFile.cpp

const zeromemory_t zeromemory;

void* _cdecl operator new(size_t cbSize, const zeromemory_t&)
{
    void *mem = ::operator new(cbSize);
    memset(mem,0,cbSize);
    return mem;
}

والآن يمكنك أن تفعل ما يلي للحصول على جديد مع ذاكرة zero'd

MyType* pMyType = new (zeromemory) MyType();

وبالإضافة إلى ذلك كنت بحاجة لفعل الأشياء الممتعة الأخرى مثل تعريف جديد [] التي هي على التوالي إلى حد ما إلى الأمام أيضا.

ولا. أيضا لا تفكر في القيام بشيء مثل:

YourClass *var = new YourClass;
memset(var, 0, sizeof(YourClass));

هل يمكن أن ينتهي التحطيم VTABLE (إذا صفك لديها واحد).

وأود أن أوصي باستخدام الصانعين لمسح الذاكرة الداخلية (المتغيرات) في صفك.

وكلا. وسوف دائما الافتراضي-تهيئة هذا البند المخصص (ق)، والتي في حالة البدائيون لا يفعل شيئا. سيكون لديك لمتابعة هذا الامر مع دعوة الأمراض المنقولة جنسيا :: uninitialized_fill_n أو ما شابه ذلك.

هل يمكن أن تفعل الزائد العالمي للnew المشغل، وأنها انتزاع الذاكرة الخام من calloc(). وبهذه الطريقة يحصل على محو الذاكرة قبل الصانعين الحصول على لتشغيل ذلك لا يوجد أي مشاكل هناك.

وسوف أي الفئة التي يتجاوز جديدة من تلقاء نفسها لا تحصل الخاصة بك calloc() القائم على new، ولكن بعد تلك الفئة يجب تهيئة نفسها بشكل صحيح على أي حال.

لا تنس أن تجاوز كلا new وdelete والإصدارات مجموعة ...

وشيء من هذا القبيل:

#include <exception> // for std::bad_alloc
#include <new>
#include <stdlib.h> // for calloc() and free()

void* operator new (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc(); 
 return p;
}


void operator delete (void *p)
{
 free(p); 
}

void* operator new[] (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc();
 return p;
}

void operator delete[] (void *p)
{
 free(p); 
}

لاحظ أن هذه الإصدارات بسيطة ليست بالضبط تماما ما ينبغي أن تكون - يجب تشغيل المشغل new في حلقة استدعاء new_handler (إذا تم تثبيت واحد) ورمي فقط باستثناء bad_alloc إذا لم يكن هناك new_handler. أو شيء من هذا القبيل، سآخذ للبحث عنه وتحديث لاحقا.

وأوه، وكنت قد ترغب أيضا في تجاوز النسخة no_throw كذلك.

ويمكنني استخدام ماكرو:

#define newclear(TYPE) new(calloc(sizeof(TYPE), 1)) TYPE();

واستخدامه:

Whatever* myWhatever = newclear(Whatever);

و(هذا يستخدم "وضع جديد" مثل بعض الحلول الأخرى هنا)

وNo.You أن الصفر الذاكرة يدويا بها. تذكر، new لا يقتصر فقط على تخصيص الذاكرة، ولكن أيضا حول تهيئة عبر الصانعين. هذا هو المكان calloc هو مفيد في C (التي لا يكون لها وظائف مهيئ). أنت حر لكتابة المجمع على new أو حتى استخدام calloc، ولكن في معظم الوقت لعدم POD-كائنات هذا لا معنى كبير.

وإذا كنت لا نصر باستخدام new، يمكنك ببساطة استخدام ناقلات: vector<char> buffer; buffer.resize(newsize); وسيتم ركزت المحتوى

class MyClass {
    public:
    void* operator new(size_t bytes) {
        return calloc(bytes, 1);
    }
}

ويمكنك تجاوز مشغل عالمي جديد إذا أردت.

ويمكنك أن تقول:

vector <char> v( 100, 0 );

والتي تخلق مجموعة متجاورة من 100 حرفا باستخدام جديدة، وinitialises كل منهم إلى الصفر. يمكنك ثم الوصول إلى مجموعة مع شركة ناقلات في []، أو عن طريق القيام:

char * p = &v[0];
p[3] = 42;

ملاحظة هذه تحررك أيضا من الحاجة إلى استدعاء حذف لتحرير الذاكرة المخصصة.

نعم.

int* p_scalar = new int(5);//Does not create 5 elements, but initializes to 5

لصفائف يمكنك استخدام شيء من هذا القبيل memset. للنوافذ استخدام ZeroMemory أو SecureZeroMemory.

تعديل: الرجاء رؤية @ آخر litb، وقال انه يظهر كيف يمكن تهيئة 0 للصفائف باستخدام التهيئة غير المباشرة مثل أعلى

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top