why does not "g++ -Wall" give warning message when compiling the following code?
登录 | 论坛导航 -> 华新鲜事 -> 求学狮城 | 本帖共有 10 楼,分 1 页, 当前显示第 1 页 : 本帖树形列表 : 刷新 : 返回上一页
<<始页  [1]  末页>>
作者:icky (等级:15 - 最接近神,发帖:7923) 发表:2005-10-30 00:44:48  楼主  关注此帖评分:
why does not "g++ -Wall" give warning message when compiling the following code?
When u run the code, you will get segmentation fault as "flag" is used after the memory released, however, the segmentation fault happens at the "delete [] darray" sentence, why is it so? I thought it should happen at "flag[i] = 8".

the compiler should be able to detect such mistake, why does not "g++ -Wall" give any warning message?
please reply.

#include <iostream>

using namespace std;

int main ()
{
bool * flag = new bool[8];
delete [] flag;
double * darray = new double[10];
for (int i = 0; i < 8; i ++)
flag[i] = true;
cout << "before releasing darray" << endl;
delete [] darray;
cout << "darray released" << endl;
return 0;
}

This page is intentionally left blank
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:hash (等级:7 - 出类拔萃,发帖:5077) 发表:2005-10-30 06:28:53  2楼 评分:
using linux/glibc? Segfault because you damaged the link list
of freed memory chunks.

bype 0-8 of a freed memory chunk contains pointers to the previous/next freed chunks. in

for (int i = 0; i < 8; i ++)
flag[i] = true;

you destroyed the link list. When you try to free the next chunk (darray), free() tries to merge the two adjacent freed chunks. As the link list is corrupted, you see a segfault.

There are two ways to avoid segfault with you wrong program:
1.
#include <iostream>

using namespace std;

int main ()
{
bool * flag = new bool[16];
delete [] flag;
double * darray = new double[10];
for (int i = 0; i < 8; i ++)
flag[8+i] = true;
cout << "before releasing darray" << endl;
delete [] darray;
cout << "darray released" << endl;
return 0;
}

In this case, you didn't touch the first 8bytes, so you don't get a segfault.


2.

#include <iostream>

using namespace std;

int main ()
{
bool * flag = new bool[8];
delete [] flag;
double * darray = new double[1];
for (int i = 0; i < 8; i ++)
flag[i] = true;
cout << "before releasing darray" << endl;
delete [] darray;
cout << "darray released" << endl;
return 0;
}

In this case, size of darray chunk is too small, free() choose not to merger the two chunks. No segfault, for the moment.

tested on gcc4/glibc2.3

for more details, take a look at this article: http://www.phrack.org/show.php?p=57&a=9

欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:icky (等级:15 - 最接近神,发帖:7923) 发表:2005-10-30 10:20:03  3楼
using linux/glibc? Segfault because you damaged the link listof freed memory chunks. bype 0-8 of a freed memory chunk contains pointers to the previous/next freed chunks. in for (int i = 0; i < 8; i ++) flag[i] = true; you destroyed the link list. When you try to free the next chunk (darray), free() tries to merge the two adjacent freed chunks. As the link list is corrupted, you see a segfault. There are two ways to avoid segfault with you wrong program: 1. #include using namespace std; int main () { bool * flag = new bool[16]; delete [] flag; double * darray = new double[10]; for (int i = 0; i < 8; i ++) flag[8+i] = true; cout (more...)
but after
but after delete [] flag, when u try to access flag[i], it is wrong, the compiler should be aware of it
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:simon (等级:10 - 炉火纯青,发帖:6860) 发表:2005-10-30 11:15:53  4楼 评分:
delete array; not delete [] array;
delete [] arr;

is equivalant to

delete arr[0]; delete arr[1]; ... delete arr[k];


------------------------------------------------

defination from msdn:
The delete operator destroys the object created with new by deallocating the memory associated with the object.
------------------------------------------------

however your array is array of primative type bool


now try this

Class Bool
{
public bool myBool;
};

Bool *flag2 = new Bool[8];
delete [] flat2;
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:simon (等级:10 - 炉火纯青,发帖:6860) 发表:2005-10-30 11:16:41  5楼
delete array; not delete [] array;delete [] arr; is equivalant to delete arr[0]; delete arr[1]; ... delete arr[k]; ------------------------------------------------ defination from msdn: The delete operator destroys the object created with new by deallocating the memory associated with the object. ------------------------------------------------ however your array is array of primative type bool now try this Class Bool { public bool myBool; }; Bool *flag2 = new Bool[8]; delete [] flat2;
different btw 'object' and 'primitive data type'
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:hash (等级:7 - 出类拔萃,发帖:5077) 发表:2005-10-30 15:21:18  6楼
using linux/glibc? Segfault because you damaged the link listof freed memory chunks. bype 0-8 of a freed memory chunk contains pointers to the previous/next freed chunks. in for (int i = 0; i < 8; i ++) flag[i] = true; you destroyed the link list. When you try to free the next chunk (darray), free() tries to merge the two adjacent freed chunks. As the link list is corrupted, you see a segfault. There are two ways to avoid segfault with you wrong program: 1. #include using namespace std; int main () { bool * flag = new bool[16]; delete [] flag; double * darray = new double[10]; for (int i = 0; i < 8; i ++) flag[8+i] = true; cout (more...)
a mistake
2nd case:
double * darray = new double[1];
should be:
double * darray = new double[2];

double[1] needs only 8 bytes, so first chunk (released when you delete flag) is reused.

change double[2] still does not generate segfault.

欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:icky (等级:15 - 最接近神,发帖:7923) 发表:2005-10-30 15:44:12  7楼
delete array; not delete [] array;delete [] arr; is equivalant to delete arr[0]; delete arr[1]; ... delete arr[k]; ------------------------------------------------ defination from msdn: The delete operator destroys the object created with new by deallocating the memory associated with the object. ------------------------------------------------ however your array is array of primative type bool now try this Class Bool { public bool myBool; }; Bool *flag2 = new Bool[8]; delete [] flat2;
do u mean
"delete [] arr" deletes each cell
and
"delete arr" deletes the pointer itself

after "delete [] arr", the pointer "arr" still exists
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:hash (等级:7 - 出类拔萃,发帖:5077) 发表:2005-10-30 15:48:03  8楼
but afterbut after delete [] flag, when u try to access flag[i], it is wrong, the compiler should be aware of it
The default libstdc++ operator new and delete use the libc malloc and free.
since it boils down to function call, i guess g++ is not supposed to do such checking.
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:sarah (等级:6 - 驾轻就熟,发帖:5796) 发表:2005-10-30 20:03:05  9楼 评分:
do u mean"delete [] arr" deletes each cell and "delete arr" deletes the pointer itself after "delete [] arr", the pointer "arr" still exists
no la...as simon said, object vs primitive data type
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
作者:simon (等级:10 - 炉火纯青,发帖:6860) 发表:2005-10-31 01:04:01  10楼
no la...as simon said, object vs primitive data type
。。。。。。ok...
欢迎来到华新中文网,踊跃发帖是支持我们的最好方法!原文 / 传统版 / WAP版只看此人从这里展开收起列表
论坛导航 -> 华新鲜事 -> 求学狮城 | 返回上一页 | 本主题共有 10 篇文章,分 1 页, 当前显示第 1 页 | 回到顶部
<<始页  [1]  末页>>

请登录后回复:帐号   密码