【记录】memcpy后报错:segmentation fault

问题:使用v4l2框架进行图像数据采集,遇到在执行memcpy()函数时报错segmentation fault
开发环境:ubuntu和ARM开发板(Linux+Qt系统)
实验做的代码如下(只摘取关键部分代码)

unsigned char *tmpbuffer;

tmpbuffer=(unsigned char *)calloc(1,(size_t)(IMAGEWIDTH*IMAGEHEIGHT));

memcpy(tmpbuffer,mem[buf.index],buf.bytesused);

关键代码如上,包含上述代码的程序,在ubuntu中编译后可正常执行,输出图像。然后,通过交叉编译后,放在ARM开发板上运行,当程序执行到memcpy()函数时,程序退出终止,并报错:segmentation fault。
【问题原因】
因为内存分配不成功,导致后续的操作非法
【解决过程】
第一次遇到这种情况,很是奇怪,查了资料,报segmentation fault(段错误),可能是访问的内存超出了系统所分配的内存空间。从代码入手,首先先看看是否因为内存分配,在程序中分配内存后加上打印信息,判断是否分配成功,代码如下:

unsigned char *tmpbuffer;

tmpbuffer=(unsigned char *)calloc(1,(size_t)(IMAGEWIDTH*IMAGEHEIGHT));
if(tmpbuffer==NULL)
      cout<<"error"<<endl;
else
      cout<<"calloc sucessful"<<endl;
memcpy(tmpbuffer,mem[buf.index],buf.bytesused);

程序重新编译后运行,在ubuntu上没问题,但在板子上输出“error”的错误信息,也就是说,在ubuntu里分配成功了的内存,移植到了ARM开发板上是分配不成功的。经过排查,最终将代码修改如下,在对指针进行分配前,先将其置于NULL,之后再分配,如此一来,ubuntu和开发板上都可以正常运行,内存分配成功。
在这里有个疑问,也没解决,是什么样的原因导致两者之间的差异,尚且不明,如有了解的同学麻烦评论区告知,感谢!

unsigned char *tmpbuffer;
tmpbuffer=NULL;
tmpbuffer=(unsigned char *)calloc(1,(size_t)(IMAGEWIDTH*IMAGEHEIGHT));
if(tmpbuffer==NULL)
      cout<<"error"<<endl;
else
      cout<<"calloc sucessful"<<endl;
memcpy(tmpbuffer,mem[buf.index],buf.bytesused);

小结:
良好的编程习惯还是必须保持的,如上述问题,内存分配操作后,最好加上判断过程,如分配不成功,可及时找出问题,方便判断,虽然这一步在程序可正常执行时多余,但关键时刻方便调试。

另外关于malloc()和calloc()这两个函数的一些区别如下:
1.分配内存空间函数malloc

  调用形式: (类型说明符*) malloc (size) 功能:
  在内存的动态存储区中分配一块长度为”size” 字节的连续区域。函数的返回值为该区域的首地址。 “类型说明符”表示把该区域用于何种数据类型。(类型说明符)表示把返回值强制转换为该类型指针。“size”是一个无符号数。例如: pc=(char ) malloc (100); 表示分配100个字节的内存空间,并强制转换为字符数组类型, 函数的返回值为指向该字符数组的指针, 把该指针赋予指针变量pc。

2.分配内存空间函数 calloc

 calloc 也用于分配内存空间。调用形式: (类型说明符*)calloc(n,size) 功能:
 在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。(类型说明符*)用于强制类型转换。calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。
 例如: ps=(struet stu*) calloc(2,sizeof (struct stu)); 其中的sizeof(struct stu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。

简单的说是:
malloc它允许从空间内存池中分配内存,malloc()的参数是一个指定所需字节数的整数.
例如:P=(int*)malloc(n*sizeof(int));
colloc与malloc类似,但是主要的区别是存储在已分配的内存空间中的值默认为0,使用malloc时,已分配的内存中可以是任意的值。colloc需要两个参数,第一个是需要分配内存的变量的个数,第二个是每个变量的大小.
例如:P=(int*)colloc(n,colloc(int));

猜你喜欢

转载自blog.csdn.net/u011831771/article/details/78803590