动态数组delete报错问题

绿色盒子 2019-06-17 02:39:54

int n=5000;
double *temp[9]; //临时数据

for (int i=0;i<9;i++)
temp[i]=new double[n];

//赋值过程省略. . .

for (int i=0;i<9;i++)
quick_sort(temp[i],0,n);//排序


for (int i=0;i<9;i++)
delete[] temp[i];//释放报错


如上所示代码
释放时会报错(堆栈损坏),不排序就不会报错

快排代码如下

void quick_sort(double *A, int lo, int hi)
{
int i, j;
double pivot, temp;
if(lo == hi) return;
i=lo;
j=hi;
pivot= A[(lo+hi)/2];

/* Split the array into two parts */
do {
while (A[i] < pivot) i++;
while (A[j] > pivot) j--;
if (i<=j) {
temp= A[i];
A[i]= A[j];
A[j]=temp;
i++;
j--;
}
} while (i<=j);

if (lo < j) quick_sort(A, lo, j);
if (i < hi) quick_sort(A, i, hi);
}

请大家看看这是为啥
...全文
364 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
gouyanfen 2019-06-19
  • 打赏
  • 举报
回复
引用 13 楼 Mr_sandman1994 的回复:
[quote=引用 12 楼 gouyanfen 的回复:] [quote=引用 楼主 Mr_sandman1994 的回复:]

int                    n=5000;
double	        *temp[9];			//临时数据

for (int i=0;i<9;i++)
	temp[i]=new double[n];

//赋值过程省略.  .  .

for (int i=0;i<9;i++)
	quick_sort(temp[i],0,n);//排序


for (int i=0;i<9;i++)
        delete[] temp[i];//释放报错

如上所示代码 释放时会报错(堆栈损坏),不排序就不会报错 快排代码如下

void quick_sort(double *A, int lo, int hi) 
{
	int i, j;
	double pivot, temp;
	if(lo == hi) return;
	i=lo;
	j=hi;
	pivot= A[(lo+hi)/2];

	/* Split the array into two parts */
	do {
		while (A[i] < pivot) i++;
		while (A[j] > pivot) j--;
		if (i<=j) {
			temp= A[i];
			A[i]= A[j];
			A[j]=temp;
			i++;
			j--;
		}
	} while (i<=j);

	if (lo < j) quick_sort(A, lo, j);
	if (i < hi) quick_sort(A, i, hi);
}
请大家看看这是为啥
特意试了一下,你的问题在于 quick_sort(temp[i], 0, n-1);函数参数进去就有越界操作了 因为你循环里有访问了A[j],j=n,A[j]就越界了 调试了一下,没有出现错误[/quote] 您说的很对,确实是越界了 但是为什么调试报错在释放的部分,越界访问却没有报错,[/quote] 越界访问只是个按照指针读写内存的过程,不存在错于不错,只要你的进程空间你想读什么就读什么地址。界只是你心中的界,程序中只存在不同的地址不同的数据。 数组new释放出错应该是因为系统应该会维护一份new出不同对象大小的表,你用new出来的指针访问了越界地址,有可能改变了系统维护的这个表,释放是按最后的表来释放,至于具体表是怎么样子的,没研究过。
绿色盒子 2019-06-19
  • 打赏
  • 举报
回复



引用 12 楼 gouyanfen 的回复:
[quote=引用 楼主 Mr_sandman1994 的回复:]

int n=5000;
double *temp[9]; //临时数据

for (int i=0;i<9;i++)
temp[i]=new double[n];

//赋值过程省略. . .

for (int i=0;i<9;i++)
quick_sort(temp[i],0,n);//排序


for (int i=0;i<9;i++)
delete[] temp[i];//释放报错


如上所示代码
释放时会报错(堆栈损坏),不排序就不会报错

快排代码如下

void quick_sort(double *A, int lo, int hi)
{
int i, j;
double pivot, temp;
if(lo == hi) return;
i=lo;
j=hi;
pivot= A[(lo+hi)/2];

/* Split the array into two parts */
do {
while (A[i] < pivot) i++;
while (A[j] > pivot) j--;
if (i<=j) {
temp= A[i];
A[i]= A[j];
A[j]=temp;
i++;
j--;
}
} while (i<=j);

if (lo < j) quick_sort(A, lo, j);
if (i < hi) quick_sort(A, i, hi);
}

请大家看看这是为啥

特意试了一下,你的问题在于 quick_sort(temp[i], 0, n-1);函数参数进去就有越界操作了
因为你循环里有访问了A[j],j=n,A[j]就越界了

调试了一下,没有出现错误[/quote]
您说的很对,确实是越界了
但是为什么调试报错在释放的部分,越界访问却没有报错,
绿色盒子 2019-06-18
  • 打赏
  • 举报
回复
引用 8 楼 凌夜望天涯 的回复:
[quote=引用 7 楼 Mr_sandman1994 的回复:]
[quote=引用 5 楼 林多 的回复:]
尝试了一下你的代码。没有崩溃。是不是赋值的部分有问题??某些值,二次(多次)释放了?

int main()
{

int n = 5000;
double* temp[9];

for (int i = 0; i < 9; i++) {
temp[i] = new double[n];
for (int j = 5000; j>0; j--) {
*(temp[i] + j) = rand();
}
}

for (int i = 0; i < 9; i++) {
quick_sort(temp[i], 0, n);
}


for (int i = 0; i < 9; i++) {
delete[] temp[i];
}
}

那奇怪了,我的代码除了以上部分没别的,就是赋值排序,之后就释放
不排序就不会报错
一开始认为排序部分修改了指针,让指针没有指向数组首地址
但是看了代码,也调试了一下,并没有改变地址
现在就有点懵逼了[/quote]

首先不明白你排序为什么是在0 - 5000进行排序,但是你quick_sort函数的后两个参数如果是用来作为排序参考值的话,就不要又把这两个参数作为下标使用:5000已经越界了!!!那如果你的是要在-5000到0之间排序,是不是问题一目了然了。

所以,定义函数是,参数是什么意义就是应该严格按照这个意义命名,然后使用也要严格按照最初设计使用,这样自己也不会莫名其妙出错,别人用你的方法也知道怎么用,也敢用!![/quote]

没有0-5000本来就是索引号啊,数组里面的数又不是0-5000,上面这个同学只是举个例子,因为我的代码省略了赋值部分(绝对不是0-5000),用0-5000没毛病啊。
快排代码并不会越界。
gouyanfen 2019-06-18
  • 打赏
  • 举报
回复
引用 楼主 Mr_sandman1994 的回复:

int                    n=5000;
double	        *temp[9];			//临时数据

for (int i=0;i<9;i++)
	temp[i]=new double[n];

//赋值过程省略.  .  .

for (int i=0;i<9;i++)
	quick_sort(temp[i],0,n);//排序


for (int i=0;i<9;i++)
        delete[] temp[i];//释放报错

如上所示代码 释放时会报错(堆栈损坏),不排序就不会报错 快排代码如下

void quick_sort(double *A, int lo, int hi) 
{
	int i, j;
	double pivot, temp;
	if(lo == hi) return;
	i=lo;
	j=hi;
	pivot= A[(lo+hi)/2];

	/* Split the array into two parts */
	do {
		while (A[i] < pivot) i++;
		while (A[j] > pivot) j--;
		if (i<=j) {
			temp= A[i];
			A[i]= A[j];
			A[j]=temp;
			i++;
			j--;
		}
	} while (i<=j);

	if (lo < j) quick_sort(A, lo, j);
	if (i < hi) quick_sort(A, i, hi);
}
请大家看看这是为啥
特意试了一下,你的问题在于 quick_sort(temp[i], 0, n-1);函数参数进去就有越界操作了 因为你循环里有访问了A[j],j=n,A[j]就越界了 调试了一下,没有出现错误
gouyanfen 2019-06-18
  • 打赏
  • 举报
回复
引用 楼主 Mr_sandman1994 的回复:

int                    n=5000;
double	        *temp[9];			//临时数据

for (int i=0;i<9;i++)
	temp[i]=new double[n];

//赋值过程省略.  .  .

for (int i=0;i<9;i++)
	quick_sort(temp[i],0,n);//排序


for (int i=0;i<9;i++)
        delete[] temp[i];//释放报错

如上所示代码 释放时会报错(堆栈损坏),不排序就不会报错 快排代码如下

void quick_sort(double *A, int lo, int hi) 
{
	int i, j;
	double pivot, temp;
	if(lo == hi) return;
	i=lo;
	j=hi;
	pivot= A[(lo+hi)/2];

	/* Split the array into two parts */
	do {
		while (A[i] < pivot) i++;
		while (A[j] > pivot) j--;
		if (i<=j) {
			temp= A[i];
			A[i]= A[j];
			A[j]=temp;
			i++;
			j--;
		}
	} while (i<=j);

	if (lo < j) quick_sort(A, lo, j);
	if (i < hi) quick_sort(A, i, hi);
}
请大家看看这是为啥
int main() { int *temp; temp=new int[10]; int *a=new int[10];//为了不至于越界出错,一般会连续分配,等到删除temp指针才出错 temp[10]=11; printf("%d",temp[10]); getchar(); delete temp; return 0; } 你试下这个代码,应该和这个原因一样。 程序中的操作越界操作数据后,原始指针所指内存大小被破坏了,不能正确的释放了。
绿色盒子 2019-06-18
  • 打赏
  • 举报
回复
编译环境 VS2010
多次测试结果发现:递归会导致释放崩溃问题

测试了,快排,归并排序,冒泡等几种排序,只有冒泡没问题
目前不清楚原因,排序并没有改变数组指针的地址,不应该会有这样的问题
也没越界访问,报错在释放的地方,提示堆可能损坏
有碰到过的,或者知道的大哥请赐教,感谢!

凌夜望天涯 2019-06-17
  • 打赏
  • 举报
回复
引用 7 楼 Mr_sandman1994 的回复:
[quote=引用 5 楼 林多 的回复:]
尝试了一下你的代码。没有崩溃。是不是赋值的部分有问题??某些值,二次(多次)释放了?

int main()
{

int n = 5000;
double* temp[9];

for (int i = 0; i < 9; i++) {
temp[i] = new double[n];
for (int j = 5000; j>0; j--) {
*(temp[i] + j) = rand();
}
}

for (int i = 0; i < 9; i++) {
quick_sort(temp[i], 0, n);
}


for (int i = 0; i < 9; i++) {
delete[] temp[i];
}
}

那奇怪了,我的代码除了以上部分没别的,就是赋值排序,之后就释放
不排序就不会报错
一开始认为排序部分修改了指针,让指针没有指向数组首地址
但是看了代码,也调试了一下,并没有改变地址
现在就有点懵逼了[/quote]

首先不明白你排序为什么是在0 - 5000进行排序,但是你quick_sort函数的后两个参数如果是用来作为排序参考值的话,就不要又把这两个参数作为下标使用:5000已经越界了!!!那如果你的是要在-5000到0之间排序,是不是问题一目了然了。

所以,定义函数是,参数是什么意义就是应该严格按照这个意义命名,然后使用也要严格按照最初设计使用,这样自己也不会莫名其妙出错,别人用你的方法也知道怎么用,也敢用!!
绿色盒子 2019-06-17
  • 打赏
  • 举报
回复
引用 5 楼 林多 的回复:
尝试了一下你的代码。没有崩溃。是不是赋值的部分有问题??某些值,二次(多次)释放了?

int main()
{

int n = 5000;
double* temp[9];

for (int i = 0; i < 9; i++) {
temp[i] = new double[n];
for (int j = 5000; j>0; j--) {
*(temp[i] + j) = rand();
}
}

for (int i = 0; i < 9; i++) {
quick_sort(temp[i], 0, n);
}


for (int i = 0; i < 9; i++) {
delete[] temp[i];
}
}

那奇怪了,我的代码除了以上部分没别的,就是赋值排序,之后就释放
不排序就不会报错
一开始认为排序部分修改了指针,让指针没有指向数组首地址
但是看了代码,也调试了一下,并没有改变地址
现在就有点懵逼了
轻箬笠 2019-06-17
  • 打赏
  • 举报
回复
引用 3 楼 Mr_sandman1994 的回复:
嗯,谢谢,确实有这个问题,已修改
但最后的释放报错原因还不是这个,很苦恼

我觉得2L的修改有问题。我改了下
void quick_sort(double *A, int lo, int hi) 
{
int i, j;
double pivot, temp;
if(lo == hi) return;
i=lo;
j=hi;
pivot= A[(lo+hi)/2];

/* Split the array into two parts */
do {
while (i < j && A[i] < pivot) i++;
while (j > i && A[j] > pivot) j--;
if (i < j && A[i] >= pivot && A[j] <= pivot)
{
temp= A[i];
A[i]= A[j];
A[j]=temp;
if (j - i == 1)
break;
if (j - i == 2) {
i = j - 1;
break;
}
i++;
j--;
}
else
break;
} while (1);

if (lo < j) quick_sort(A, lo, j);
if (i < hi) quick_sort(A, i, hi);
}


楼主可以把自己改后的发出来看看
林多 2019-06-17
  • 打赏
  • 举报
回复
尝试了一下你的代码。没有崩溃。是不是赋值的部分有问题??某些值,二次(多次)释放了?

int main()
{

    int n = 5000;
    double* temp[9];

    for (int i = 0; i < 9; i++) {
        temp[i] = new double[n];
        for (int j = 5000; j>0; j--) {
           *(temp[i] + j) = rand();
        }
    }

    for (int i = 0; i < 9; i++) {
        quick_sort(temp[i], 0, n);
    }


    for (int i = 0; i < 9; i++) {
        delete[] temp[i];
    }
}
绿色盒子 2019-06-17
  • 打赏
  • 举报
回复
引用 2 楼 636f6c696e 的回复:
while (A[i] < pivot) i++;
while (A[j] > pivot) j--;

这里要判断i和j的边界值,不然会内存越界,改成

while (A[i] < pivot && i <= hi) i++;
while (A[j] > pivot && j >= lo) j--;

感谢,已修改。运气好没越界
最后的释放报错原因不是这个
绿色盒子 2019-06-17
  • 打赏
  • 举报
回复
引用 1 楼 轻箬笠 的回复:
你这个排序算法很奇怪诶,
如果pivot是最大的,那么while (A[i] < pivot) i++;这段执行下来,i可能会越界,会不会崩的呀?
如果pivot是最小的,那么 while (A[j] > pivot) j--;也是存在类似的问题。
楼主把越界问题处理下,再试试

嗯,谢谢,确实有这个问题,已修改
但最后的释放报错原因还不是这个,很苦恼
636f6c696e 2019-06-17
  • 打赏
  • 举报
回复
while (A[i] < pivot) i++; while (A[j] > pivot) j--; 这里要判断i和j的边界值,不然会内存越界,改成 while (A[i] < pivot && i <= hi) i++; while (A[j] > pivot && j >= lo) j--;
轻箬笠 2019-06-17
  • 打赏
  • 举报
回复
你这个排序算法很奇怪诶,
如果pivot是最大的,那么while (A[i] < pivot) i++;这段执行下来,i可能会越界,会不会崩的呀?
如果pivot是最小的,那么 while (A[j] > pivot) j--;也是存在类似的问题。
楼主把越界问题处理下,再试试

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧