在下面,您将找到一个代码(编译/运行),该代码简要地调用了一个函数,该函数在堆上动态分配数组。
#include "stdafx.h"
#include <stdio.h>
class A
{
public:
A()
{
printf ( "constructor has been called !!! \n" );
}
~A()
{
printf ( "destructor has been called !!! \n" );
}
char* f( void )
{
//char *data_raw = NULL;
data_raw = NULL;
data_raw = new char [ 20 ];
for( int i = 0; i < 20; i++ )
{
data_raw[ i ] = '0';
}
data_raw[ 0 ] = 'h';
data_raw[ 1 ] = 'e';
data_raw[ 2 ] = 'l';
data_raw[ 3 ] = 'l';
data_raw[ 4 ] = 'o';
data_raw[ 5 ] = ' ';
data_raw[ 6 ] = 'w';
data_raw[ 7 ] = 'o';
data_raw[ 8 ] = 'r';
data_raw[ 9 ] = 'l';
data_raw[ 10 ] = 'd';
data_raw[ 11 ] = '!';
return data_raw;
} //data raw ptr-var is destroyed
private:
char *data_raw;
};
int _tmain( int argc, _TCHAR* argv[] )
{
char *data = NULL;
printf( "data: %c", data );
A a;
data = a.f();
delete [] data;
return 0;
}
我的问题:
1)关于破坏动态分配的内存,我应该使用delete还是delete []?他们都编译...
2)当我使用前一个(delete)时,将调用类析构函数,而不是当我使用delete []时?
答案 0 :(得分:2)
您应该<永远>永远不要使用诸如A之类的类,尤其不要使用它的方式。
特别是:
std::unique_ptr
,std::shared_ptr
和std::weak_ptr
-适当。您的代码没有遵循这些准则!这很可怕,很危险!
我会按照您的准则重写您的代码,但是由于不清楚为什么您甚至需要方法f或A类,我最终只会遇到:
#include <iostream>
#include <string>
std::string A_f() { return "hello world"; }
int main( int argc, const char* argv[] )
{
std::cout << A_f();
}
或者只是
#include <iostream>
int main( int argc, const char* argv[] )
{
std::cout << "hello world";
}
答案 1 :(得分:1)
使用delete[]
初始化堆中的数组时调用new
,而使用delete
初始化堆中的对象时使用new
。
在旁注中,我建议您删除类的所有者。如果您在这里做什么,将会给您带来很多麻烦。删除A之外的数组。
在此示例中,没有什么阻止您在类A的析构函数中调用delete[] data_raw
。无需从A的外部对其进行修饰,甚至无需返回指向数组的指针。
class A
{
public:
A()
{
printf ( "constructor has been called !!! \n" );
data_raw = NULL;
data_raw = new char [ 20 ];
//....rest ofthe code from f( void )
//....no need to return data_raw
}
~A()
{
printf ( "destructor has been called !!! \n" );
delete [] data_raw;
}
private:
char *data_raw;
};