Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是缩小数组的有效方法吗?_C++_Arrays - Fatal编程技术网

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);istd::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