| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1123 人关注过本帖, 1 人收藏
标题:使用realloc分配不成功,同时加free提示triggered a breakpoint. 请问这是什 ...
只看楼主 加入收藏
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
结帖率:100%
收藏(1)
已结贴  问题点数:20 回复次数:17 
使用realloc分配不成功,同时加free提示triggered a breakpoint. 请问这是什么意思
一个简单的测试动态数组的程序
程序代码:
# include <stdio.h>
# include <malloc.h>

int main(void)
{
    int a[5];
    int * pArr;
    int len;
    int i;

    //创造动态数组
    printf("请输入想要的元素个数:");
    scanf_s("%d", &len);
    pArr = (int *)malloc(sizeof(int) * len);  //开头的pArr本身就是地址变量,不要用int *pArr=... ;
                                              //(int *)强制转换告诉是int类型地址变量,让系统知道按4个字节一个变量分配

    //对动态数组进行赋值
    printf("对元素进行赋值:\n");
    for (i = 0; i < len; ++i)
        scanf_s("%d", &pArr[i]);      //与数组一样的使用方式pArr代表第一个元素地址,*(pArr+1)就是第二个也就是pArr[1]
    
    //对数组进行输出
    printf("一维数组的内容是:\n");
    for (i = 0; i < len; ++i)
        printf("%d\n", pArr[i]);


    //出错,提示triggered a breakpoint.
    realloc(pArr, 100);
    printf("\n%d\n", sizeof(*pArr) );
    free(pArr);                 //释放后pArr所指向的地址的内存不再存在,但pArr所保存的"地址"依然可以存在

    
    return 0;
}



最后修改的时候是重新分配了100个字节,想看看最后是不是确实分配了100个,

1.发现如果加了最后一句free(pArr)会提示triggered a breakpoint,这时候应该已经执行完上面了,这是什么意思啊?
2.删除free后就不会出错,但最后的结果是:

请输入想要的元素个数:2
对元素进行赋值:
3
4
一维数组的内容是:
3
4

4

结果并没有修改字节数,这是为什么呢
搜索更多相关主题的帖子: 动态 
2015-09-13 11:24
林月儿
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:湖南
等 级:版主
威 望:138
帖 子:2277
专家分:10647
注 册:2015-3-19
收藏
得分:0 
申请没使用吧…至于触发断点报错…无知啦

剑栈风樯各苦辛,别时冰雪到时春
2015-09-13 11:46
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 2楼 林月儿
是说的那个a数组吗?但是我是想测试那个动态数组啊 a数组放那应该没有关系啊
2015-09-13 12:01
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
错的原因有多处。首先自己去查一查recalloc()的用法再说。

授人以渔,不授人以鱼。
2015-09-13 12:56
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 4楼 TonyDeng
查到了,我是在视频中看别人这么用的,原来是错的,修改如下:  
pArr=(int *)realloc(pArr, 100);
    printf("\n%d\n", sizeof(*pArr) );

但返回的结果仍然是4..其他部分看了几遍不知道哪里有错,前面也可以正确执行..
2015-09-13 15:32
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 5楼 uswood
返回的是int尺寸

授人以渔,不授人以鱼。
2015-09-13 17:20
erty1001
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:331
专家分:1433
注 册:2014-8-31
收藏
得分:2 
简单说说:
我建议使用C++ 的new 和delete 你一定会爱上它
将来混合着C++和C的语言 用C++的编译器最好了
2015-09-13 17:27
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 6楼 TonyDeng
明白了,最终即便指向那个数组,但实际只保存第一个的地址,而本身转换成了int型所以sizeof会是4。
但如果是这样的话要用什么才能表示那整个动态空间呢?
2015-09-13 20:35
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 7楼 erty1001
谢谢建议!学到的时候一定详细看看
2015-09-13 20:36
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:10 
以下是引用uswood在2015-9-13 20:35:29的发言:

明白了,最终即便指向那个数组,但实际只保存第一个的地址,而本身转换成了int型所以sizeof会是4。
但如果是这样的话要用什么才能表示那整个动态空间呢?


1.不是转换。p是指针,*p是解引用,此时对象为指针所指向的变量,而sizeof()是求对象尺寸的,由于你声明的指针是int* p,即p所指向的对象被声明为int,则sizeof()所求者亦为int的尺寸。注意:sizeof()其实是不管对象具体是什么的,它祗按对象所归属的数据类型来返回,故sizeof(x)和sizeof(int)并无区别。这种情况不存在转换(实际上没有什么机制是转换的),编译器就是根据声明int* p来返回,int* p和int *p等价,sizeof(*p)就等价于sizeof(int)。若是sizeof(p),则是指针变量自身的尺寸,在32位机器和编译环境中,它的值就是4,不管指针指向什么数据类型,这个值都是4。事实上,sizeof()不是函数,而是编译器在编译期间根据环境设置立即得到的常数,不用在运行时再运算,它与宏的性质相似。

2.变量,是一个可以用名字来访问的数据存储空间,比如int x,是在栈上分配的变量,通过变量名x就可以访问到这个数据,它实际上是一个地址的名称,x可以被赋予不同的值,但地址始终是这个地址。指针也是一个变量,但它所储存的值有特殊意义,当一个变量被视为指针的时候,程序员假定这个变量的值是某个地址,而要取出这个被指向的地址的数据,需要使用解引用操作符约定。通常,在栈上分配的变量或空间(数组是一个连续储存若干同类变量的空间),都有变量名,这种变量和空间,其实是不需要使用指针访问的。但在堆上分配的数据,却是没有变量名的,这种数据,就一定要使用指针来访问。malloc()的动作,就是在堆上申请并分配得一块存储空间,由于没有变量名,所以把这块空间的地址返回来,好让程序员访问这块空间的数据,因此,返回的指针就是那整个动态空间的入口点,也是唯一的访问手段。

返回你原先的问题。recalloc()是重新分配堆空间,它的函数用法是void* recalloc(void* old_ptr, int size),第一个参数是原先已分配空间的指针,表示要对这块空间重新分配,要求最终的空间大小是第二个参数size所表示的字节,然后,把最终空间的地址返回来。这个动作有不同的操作:如果size比原先的小,那很好办,把尺寸边界缩小就可以了,此时,返回的指针就是原来空间的指针;但如果要求的新空间比原来的大,那么麻烦就来了,因为此时不可能简单地扩张空间边界(因为极可能已被分配给别的申请了),那么,内存管理系统就要另外找一块连续的满足尺寸条件的空间来替代原来的空间,并且要把原来空间中的数据搬动到新空间中,此时,函数返回的空间地址,就不再是原来的地址,故函数不是直接使用第一个参数的指针返回新空间,而是另外返回一个指针。这是很严重的问题,很多人并不知道recalloc()既然已经有指针参数,为何还要再返回一个指针,以为那是多余的,更会误以为重新分配后的空间仍可以用原来的指针入口。你原先的崩溃现象,就出在这里,新申请的空间比原来的大,位置已经挪动了,但你却用原来的指针去访问数据,那就是野指针,故只有你使用函数返回的指针作为访问指针时,结果才正确。不明白这个道理的人,会乱用recalloc(),其危险根据上面解释可知。

另外一个隐蔽的问题,也属于指针问题,就是假定你原先动态分配的指针是p1,然后又使用另外的p2、p3之类的指针指向同一个空间(通过p2 = p1、p3 = p1的赋值操作即可,尤其是在函数参数传递时,实际上已经复制了一份指针),那么若偶然recalloc()之后,p1的指向已经改变(或被free()掉),而此时p2、p3等是不知道的,你的代码极可能还会使用p2、p3去访问数据,这种正是高级程序员也难以防范的错误,而且几乎无法排查。这也是许多比C高级的程序如C++、C#、Java等戒用指针的原因,那些课程的书上都有详细讲解为什么会戒用指针。

指针的隐患是在这些地方!

如果按你说的1楼的代码是教学视频上看来的,那么可知做这个教学的人自己也是乱来,看这种东西学习,后果可想而知。不过,很多人以为偶然的成功,而当作必胜,学到错误的方法和知识而不知道,一直那样做下去,还自觉学会了,那才最可怕。出了错误还好,就怕不出错误。

授人以渔,不授人以鱼。
2015-09-14 03:52
快速回复:使用realloc分配不成功,同时加free提示triggered a breakpoint. 请问 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016235 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved