请教有关 malloc(): memory corruption: 出错的原因&解决方法

时间:2021-10-17 20:33:29
我在Red Hat 9,CDT下 , 程序死在 temp=(U8*) malloc(sizeof(U8)*48).报错如下。请教原因&解决方法,谢谢。 
 
* glibc detected *** /home/duzc/workspace/trillium_sip_zhangsc/sip/so_acc: malloc(): memory corruption: 0x09fb3da0 *** 
======= Backtrace: ========= 
/lib/libc.so.6[0x763fbb] 
/lib/libc.so.6(__libc_malloc+0x7e)[0x76512e] 
/home/duzc/workspace/trillium_sip_zhangsc/sip/so_acc[0x8258f87] 
/home/duzc/workspace/trillium_sip_zhangsc/sip/so_acc[0x8137ab3] 
/home/duzc/workspace/trillium_sip_zhangsc/sip/so_acc[0x821f1b2] 
/home/duzc/workspace/trillium_sip_zhangsc/sip/so_acc[0x813842c] 
/home/duzc/workspace/trillium_sip_zhangsc/sip/so_acc[0x8261ca5] 
/lib/libpthread.so.0[0x87343b] 
/lib/libc.so.6(clone+0x5e)[0x7cafde] 
======= Memory map: ======== 

14 个解决方案

#1


堆被破坏了吧。一般原因是内存访问越界,但是出错的地方往往不是导致问题的地方,从这里是看不出的(当然也不可能立刻有解决方法,你需要找到导致问题的地方先)
这种内存访问越界一般需要代码走查和单步跟踪,看看到底哪边越界了

#2



malloc 不一定是线程安全的。其中有些早期版本的 glibc 中使用的不是线程安全的。线程安全的版本好像也是有的。貌似叫 ptmalloc,具体记不清楚了。

LZ 最好考虑加保护,比如临界段。

#3


谢谢ls,2位!请问如何写临界段?小弟刚学C

#4


用calloc行吗?

#5



你好像是在 linux 下。用的是 pthread 。就用 pthread_mutex_t 好了。互斥量。

#6



在网上查了一下。好像很多帖子都说linux下malloc是线程安全的。我不想LZ做无用功,所以请你查一下手册,确认一下是否是线程安全的。

另外,malloc失败还有可能如 阿荣 所述。具体说就是,管理堆内存组块的元数据被破坏了。这有可能由不当的使用指针引起的。检查一下指针的使用。

#7


先找到错误再说,否则你换其他api不一样有错?
2楼说多线程,那么你使用多线程没有?

引用 4 楼 strive4java 的回复:
用calloc行吗?

#8


帖代码吧,你用到多线程了?

#9


谢谢楼上几位,请问如何加临界段

#10


我的代码如下,程序主要是将sip消息头的信息取出来,程序本来还有许多类似取callIdfo的操作,为了帖子美观删了:
S16 getRegInfo(SoEvnt *evnt,U8 **callIdInfo,int *cSeqInfo) {

SoCSeq *cSeq;     /* Ptr to cSeq*/
TknStrOSXL *callId; /* Ptr to callId*/

/*search Cseq */
printf("Cseq is ok!\n");
if (soCmFindHdrChoice(evnt, (U8 **)&cSeq, 
SO_HEADER_GEN_CSEQ) != ROK) {
printf("Cseq isn't ok!\n");
RETVALUE(RFAILED);
}

*cSeqInfo=cSeq->cSeqVal.val;
printf("CSeq=%d\n", *cSeqInfo);


/*search Callid */
if (soCmFindHdrChoice(evnt, (U8 **)&callId, 
SO_HEADER_GEN_CALLID) != ROK) {
printf("CAllID isn't ok!\n");
RETVALUE(RFAILED);
}
printf("*callIdInfo is %x\n",*callIdInfo);
        /*程序死在下一句上*/
*callIdInfo = (U8*)malloc(sizeof(U8) * (callId->len+2));

        strcpy(*callIdInfo,callId->val);
printf("*callIdInfo is %x\n",*callIdInfo);
fflush(stdout);

}

#11


继续求教

#12


很多东西看不出来的,不是虚心求解就行的,需要自己去debug的
除非特别常见、特别明显的东西才可能被很快看出来,别人也不是神仙
引用 11 楼 strive4java 的回复:
继续求教

#13


对于C语言库出现malloc, free异常时,解决问题一般出在内存越界访问的情况下。
C语言库的malloc与free需要保存相关的分配数据在内存的前端或者后端,如果被越界访问,将使程序无法正确完成分配与释放。一般情况下free异常比较常见。
解决问题的一般方法是找到出现异常的分配函数,然后将调用栈显示,并依调用栈,查看本地调用前是否有内存越界访问情况发生,一般就可以找到问题所在的位置,仔细检查写内存的地方。

#14


callIdInfo原先不是有数据的么,你为什么要重新malloc啊?
不过这样只会内存泄漏,输出callId->len看看是多大把。。。

#1


堆被破坏了吧。一般原因是内存访问越界,但是出错的地方往往不是导致问题的地方,从这里是看不出的(当然也不可能立刻有解决方法,你需要找到导致问题的地方先)
这种内存访问越界一般需要代码走查和单步跟踪,看看到底哪边越界了

#2



malloc 不一定是线程安全的。其中有些早期版本的 glibc 中使用的不是线程安全的。线程安全的版本好像也是有的。貌似叫 ptmalloc,具体记不清楚了。

LZ 最好考虑加保护,比如临界段。

#3


谢谢ls,2位!请问如何写临界段?小弟刚学C

#4


用calloc行吗?

#5



你好像是在 linux 下。用的是 pthread 。就用 pthread_mutex_t 好了。互斥量。

#6



在网上查了一下。好像很多帖子都说linux下malloc是线程安全的。我不想LZ做无用功,所以请你查一下手册,确认一下是否是线程安全的。

另外,malloc失败还有可能如 阿荣 所述。具体说就是,管理堆内存组块的元数据被破坏了。这有可能由不当的使用指针引起的。检查一下指针的使用。

#7


先找到错误再说,否则你换其他api不一样有错?
2楼说多线程,那么你使用多线程没有?

引用 4 楼 strive4java 的回复:
用calloc行吗?

#8


帖代码吧,你用到多线程了?

#9


谢谢楼上几位,请问如何加临界段

#10


我的代码如下,程序主要是将sip消息头的信息取出来,程序本来还有许多类似取callIdfo的操作,为了帖子美观删了:
S16 getRegInfo(SoEvnt *evnt,U8 **callIdInfo,int *cSeqInfo) {

SoCSeq *cSeq;     /* Ptr to cSeq*/
TknStrOSXL *callId; /* Ptr to callId*/

/*search Cseq */
printf("Cseq is ok!\n");
if (soCmFindHdrChoice(evnt, (U8 **)&cSeq, 
SO_HEADER_GEN_CSEQ) != ROK) {
printf("Cseq isn't ok!\n");
RETVALUE(RFAILED);
}

*cSeqInfo=cSeq->cSeqVal.val;
printf("CSeq=%d\n", *cSeqInfo);


/*search Callid */
if (soCmFindHdrChoice(evnt, (U8 **)&callId, 
SO_HEADER_GEN_CALLID) != ROK) {
printf("CAllID isn't ok!\n");
RETVALUE(RFAILED);
}
printf("*callIdInfo is %x\n",*callIdInfo);
        /*程序死在下一句上*/
*callIdInfo = (U8*)malloc(sizeof(U8) * (callId->len+2));

        strcpy(*callIdInfo,callId->val);
printf("*callIdInfo is %x\n",*callIdInfo);
fflush(stdout);

}

#11


继续求教

#12


很多东西看不出来的,不是虚心求解就行的,需要自己去debug的
除非特别常见、特别明显的东西才可能被很快看出来,别人也不是神仙
引用 11 楼 strive4java 的回复:
继续求教

#13


对于C语言库出现malloc, free异常时,解决问题一般出在内存越界访问的情况下。
C语言库的malloc与free需要保存相关的分配数据在内存的前端或者后端,如果被越界访问,将使程序无法正确完成分配与释放。一般情况下free异常比较常见。
解决问题的一般方法是找到出现异常的分配函数,然后将调用栈显示,并依调用栈,查看本地调用前是否有内存越界访问情况发生,一般就可以找到问题所在的位置,仔细检查写内存的地方。

#14


callIdInfo原先不是有数据的么,你为什么要重新malloc啊?
不过这样只会内存泄漏,输出callId->len看看是多大把。。。