strncpy引起的stack smashing detected内存溢出
一.遇到的问题
今天在写一段字符串提取的代码时候,出现了内存溢出,找了好久也没有找到。因为以前用strcpy因为没有数量限制,当字符串最后没有\0时候,就会一直覆盖,造成内存溢出。后来改用char *strncpy(char *dest, const char *src, int n),最后一个参数是字符数,当超过这个个数的时候,会自动停止复制。
二.发现问题
在检查了所有代码都没有问题后,觉得应该是strncpy的问题,于是我只留下strncpy,发现只要最后的一个参数大于dest的长度,就会出现内存溢出。
三.问题分析
以前认为,dest的n长度内,只会在字符串的最后一个字符后面加一个\0,其实是加减去有效字符个数的\0,如果dest的长度不足以容纳多出去的\0就会写出界。
例如:
int dest[3];
//dest只有3个字符,刚好容纳"hi"加上一个\0
//但是后面传入了5的参数,遇到\0并不会停止,而是往dest[3],dest[4]继续写入\0造成溢出。
strncpy(dest,"hi",5);
四.分享一下我写的字符串提取代码
经过调试没有什么问题了。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
static int strCut(char *src,char *des,char *beginStr,char *endStr)
{//复制出,第一个开始符和开始符后第一个结束符之间的字符串。
int lengthTotal;
int lengthBeginStr;
char *begin;
char *end;
lengthTotal=strlen(src);
lengthBeginStr=strlen(beginStr);
if(lengthTotal>0)
{
begin=strstr(src,beginStr);
if(begin)
{
if(endStr[0]==0)
{//空字符表示取到末尾
strncpy(des,begin+lengthBeginStr,strlen(begin+lengthBeginStr)+1);
return 1;
}
else
{
end=strstr(begin+lengthBeginStr,endStr);
if(end)
{
int tempLength;
if(begin>end)
{
tempLength=begin-end;
}
else
{
tempLength=end-begin;
}
strncpy(des,begin+lengthBeginStr,tempLength-lengthBeginStr);
printf("des:%s\r\n",des);
return 1;
}
else
{
return 0;
}
}
}
else
{
return 0;
}
}
return 0;
}
int main()
{
char *src="ifconfig eth0 192.168.1.123 up netmask 255.255.255.0";
char IP[32];
char netmask[32];
memset(IP,0,sizeof(IP));
memset(netmask,0,sizeof(netmask));
strCut(src,IP,"eth0 "," up");
strCut(src,netmask,"netmask ","");
printf("IP:%s,netmask:%s\r\n",IP,netmask);//IP:192.168.1.123,netmask:255.255.255.0
return 0;
}