C++ 这是缩小数组的有效方法吗?
我想取一个大小为C++ 这是缩小数组的有效方法吗?,c++,arrays,C++,Arrays,我想取一个大小为N的数组,并将其缩小为一个大小为M的数组,而不需要来回复制。下列各项是否有效?我试着执行代码,结果成功了。但我想知道这是否是正确的,一般来说,并且不依赖于编译器 int main(int argc, char* argv[]) { srand(time(NULL)); int N = atoi(argv[1]); int M = atoi(argv[2]); double* a
N
的数组,并将其缩小为一个大小为M
的数组,而不需要来回复制。下列各项是否有效?我试着执行代码,结果成功了。但我想知道这是否是正确的,一般来说,并且不依赖于编译器
int main(int argc, char* argv[]) {
srand(time(NULL));
int N = atoi(argv[1]);
int M = atoi(argv[2]);
double* a = new double[N];
double RANDMAX = RAND_MAX;
std::cout << "Displaying 'a'..." << std::endl;
for (int k=0; k<N; ++k) {
a[k] = rand()/RANDMAX;
std::cout << a[k] << std::endl;
}
double* b = new double[M];
b = a;
delete [] a;
std::cout << "Displaying 'b'..." << std::endl;
for (int k=0; k<M; ++k) {
std::cout << b[k] << std::endl;
}
delete [] b;
}
intmain(intargc,char*argv[]){
srand(时间(空));
int N=atoi(argv[1]);
int M=atoi(argv[2]);
双精度*a=新双精度[N];
双随机最大值=随机最大值;
标准::cout
在这之后使用b
或a
是UB,因为b
指向与a
相同的数组/位置。它们在赋值后表示相同的数组。因此delete[]b;
在两次删除数组时也是UB。不,您所做的是未定义的行为
首先,您在double*b=new double[M];
行中指定的数组永远不会被释放,因为您在下一行重新指定了指向该内存的唯一指针。(b=a;
)。这是一个典型的内存泄漏
其次,在下一行delete[]a;
中删除a
和b
指向的数组。这意味着a和b现在都指向释放的内存,可以随时重新分配,然后可以被完全无关的数据覆盖。不,您泄漏了最初分配给b的内存
double *b = new double[M];
b = a; // the memory initially pointed by b is lost ...
同样,您两次删除相同的内存位置(Paranix已经发布了这一点),纯粹是出于运气,您的程序一直在运行
这里有一个有效的解决方案
int Num(3), shrunkNum(2);
double *a = (double*)malloc(Num*sizeof(double));
a[0] = 0;
a[1] = 1;
a[2] = 2;
// realloc shrinks memory after copying the contents up to the new size
a = (double*)realloc(a, shrunkNum*sizeof(double));
for (int i(0); i < shrunkNum; ++i)
{
std::cout << a[i] << std::endl;
}
free(a); // how to delete the block pointed by a
intnum(3),shrinknum(2);
double*a=(double*)malloc(Num*sizeof(double));
a[0]=0;
a[1]=1;
a[2]=2;
//realloc在将内容复制到新大小后收缩内存
a=(双精度*)realloc(a,ShrinkNum*sizeof(双精度));
for(int i(0);i std::cout否,如其他地方所述,此代码是错误的,事实上,这些操作(新建、删除)的组合不会在不复制数据的情况下达到您的目的
有一个函数realloc()可以完全满足您的需要,但是您应该只在分配了malloc()的内存上使用它
标准的库函数,如向量有重新分配的能力。这是首选的方法。
我的幼稚C++知识表明,每一个新的都必须与删除配对。因此,在这种情况下,我们不需要<代码>删除[]b/COD>?@ LeLeeFulkNER,您已经用“代码>删除”删除它。a;
.b指向与后面的a相同的数组assignment@LeslieFaulkner:您的天真知识是否告诉您b=new double[M];b=something;
是内存泄漏?因为它是内存泄漏。您丢失了刚才分配的数组的地址,因此无法再将其与delete[]配对
的数组。@LeslieFaulkner您确实需要另一个删除[]
的新[]
在引入b
的行中,但是你需要的指针在a=b;
上丢失了。你有内存泄漏。我的收缩
是什么意思?你是说扔掉第n个元素?还是只保留前M个元素?@PeterM我只想保留第一个M
元素。所以实际上你想做在第M个元素之后取消释放内存?但是不想复制任何数据?我相信如果你使用new
和delete
,你就不能这样做。使用malloc
你可以realloc
查看david.pfx的回答谢谢。我不知道这可以用malloc和realloc来完成。谢谢Nikos和Peter M。别忘了在非基本类型中使用placement new!如果类型不平凡,那么无论如何也不能使用realloc
。谢谢Nikos。但在我的情况下,内存可能很重要。向下重新分配的原因是我只知道前面大小的上限。此外,我不想使用vector
。另外,我从that realloc不会复制内容(这正是我想要的)。
int Num(3), shrunkNum(2);
double *a = (double*)malloc(Num*sizeof(double));
a[0] = 0;
a[1] = 1;
a[2] = 2;
// realloc shrinks memory after copying the contents up to the new size
a = (double*)realloc(a, shrunkNum*sizeof(double));
for (int i(0); i < shrunkNum; ++i)
{
std::cout << a[i] << std::endl;
}
free(a); // how to delete the block pointed by a