strcat函数链接字符串,目标串内容被覆盖问题

ziyue007 2017-01-19 11:13:11
如题,Linux下C程序使用strcat时候dst中内容被src内容覆盖,不明所以,下边附上代码,求大神解救



#include <sys/statfs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

//字符串转换成16进制
inline char *CharArrayToHexString(char* pOut, const char* pInput, const int nInLen)
{
const char* chHexList = "0123456789ABCDEF";
int nIndex = 0;
int i=0, j=0;
for (i=0, j=0;i<nInLen;i++, j+=2)
{
nIndex = (pInput[i] & 0xf);
pOut[i*2+1] = chHexList[nIndex];
nIndex = ((pInput[i]>>4) & 0xf);
pOut[i*2] = chHexList[nIndex];
}
//printf("pOut hexString:%s\n",pOut);
return pOut;
}
//生成随机字符串
void get_rand_str(char s[],int number,char szHex[])
{
char str[64] = "00123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int i;
char ss[2] = {0};
srand((unsigned int)time(0));
for(i=1;i<=number;i++){
sprintf(ss,"%c",str[(rand()%62)+i]);
//printf("rand:%s\n",ss);
strcat(s,ss);
}
//将8个字符换成十六进制串表示
CharArrayToHexString(szHex, s, nLen);
nLen = 2*nLen;
szHex[nLen] = '\0';
printf("szHex : %s\n",szHex);
}

int main()
{
char strTxt[4096]={0};

char s[8];
char sz[17] = {0};
int length = 0;
int i = 0;
while(1){
if(strlen(strTxt)<=4096){
get_rand_str(s,8,sz);
strncat(strTxt,sz,strlen(sz));
printf("strTxt:%s ;sz length %d;strTxt length:%d\n",strTxt,strlen(sz),strlen(strTxt));
memset(sz,0x0,20);
memset(s ,0x0,8 );
usleep(50);
}
else{
break;
}
}
}



程序大概就是这么个简单的东西,我把程序编译后再Ubuntu上运行很正常,交叉编译后放到ARM系统上,在main函数中的while循环中,strcat(strncat)函数就会出现,dst内容被src内容完全覆盖掉,怎么也不能拼接字符串了,不明所以啊,都是用的标准C函数,不知道到底为啥,就大神解救,在线急等
...全文
451 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
自信男孩 2017-01-19
  • 打赏
  • 举报
回复
sz length 14;strTxt length:4104 strTxt长度越界了
www_adintr_com 2017-01-19
  • 打赏
  • 举报
回复
if(strlen(strTxt)<=4096): 在 strlen(strTxt)==4096 的时候, 再执行你下面的语句访问就越界了
ziyue007 2017-01-19
  • 打赏
  • 举报
回复
引用 1 楼 cfjtaishan 的回复:
你的程序有error,语法错误哦
我删掉了一些没用的,多删掉了一行代码 int nLen = strlen(s); 应该是这个没有定义吧,在37行代码前边放上这个应该就不会有语法错误了,程序的错误不是这个
自信男孩 2017-01-19
  • 打赏
  • 举报
回复
你的程序有error,语法错误哦
cutmelon 2017-01-19
  • 打赏
  • 举报
回复
闲着没事,用代码实现了一下,参考参考吧
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

//生成随机字符串
void get_rand_str(int number,char szHex[])
{
	char str[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	int len=strlen(str);
	char ss[3];

	szHex[0]=0;
	for (int i=0;i<number;i++)
	{
		ss[0]=0;
		sprintf(ss,"%X",str[rand()%len]);
		strcat(szHex,ss);
	}
	printf("szHex : %s\n",szHex);
}

int main()
{
	srand((unsigned int)time(0));

	char strTxt[4096]={0};
	char sz[20]={0};
	while (strlen(strTxt)<4095)
	{
		get_rand_str(8,sz);
		strncat(strTxt,sz,strlen(sz));
		//usleep(50);
	}

	return 0;
}
ziyue007 2017-01-19
  • 打赏
  • 举报
回复
感谢各位大虾,很久不在Linux下写ARM上的C程序了,完全蒙圈,问题解决了,越界问题也清理了,谢谢各位大虾的帮助,分数不多,分给大家,马上结贴
赵4老师 2017-01-19
  • 打赏
  • 举报
回复
“多一少一”问题占程序员常犯错误的10%以上! 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断,掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个? <、<=、==、>、>=中的哪个?
cutmelon 2017-01-19
  • 打赏
  • 举报
回复
看来看去应该是字符串和字符数组这两个东西分不清,用乱了
自信男孩 2017-01-19
  • 打赏
  • 举报
回复

#include <sys/statfs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

//字符串转换成16进制
inline char *CharArrayToHexString(char* pOut, const char* pInput, const int nInLen)
{
    const char* chHexList = "0123456789ABCDEF";
    int nIndex = 0;
    int i=0, j=0;
    for (i = 0, j = 0; i<nInLen;i++, j+=2)
    {
        nIndex = (pInput[i] & 0xf);
        pOut[i*2+1] = chHexList[nIndex];
        nIndex = ((pInput[i]>>4) & 0xf);
        pOut[i*2] = chHexList[nIndex];
    }
    //printf("pOut hexString:%s\n",pOut);
    return pOut;
}
//生成随机字符串
void get_rand_str(char s[], int number,char szHex[])
{
    char str[64] = "00123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    int i;
    char ss[2] = {0};
    srand((unsigned int)time(0));
    for(i = 1;i <= number;i++){
        sprintf(ss,"%c",str[(rand()%62)+i]);
        //printf("rand:%s\n",ss);
        strcat(s, ss);
    }
    int nLen = strlen(s);
    printf("%d: %d\n", __LINE__, nLen);
    //将8个字符换成十六进制串表示
    CharArrayToHexString(szHex, s, nLen);
    nLen = 2*nLen;
    szHex[nLen] = '\0';
    printf("szHex : %s\n",szHex);
}

int main()
{
    char strTxt[4096]={0};

    char s[12] = {0};
    char sz[20] = {0};

    while(1){
        if(strlen(strTxt)<=4096){
            get_rand_str(s, 8, sz);
            if (strlen(strTxt) + strlen(sz) > 4096-1)
                break;
            strncat(strTxt, sz, strlen(sz));
            printf("strTxt:%s ;sz length %d;strTxt length:%d\n",strTxt, strlen(sz), strlen(strTxt));
            memset(sz, 0x0, sizeof(sz));
            memset(s, 0x0, sizeof(s));
            //usleep(50);
        }
        else{
                break;
        }
    }
}
main函数中的s也是越界的。s是8个字符空间,而你往里面放了8个字符没有'\0'的空间; 在ARM板上运行注意要字节对齐吧,因为ARM的指令和X86是不一样的。X86是复杂指令集,而arm是简单的指令集,建议以4字节方式对齐。
二进制脑袋 2017-01-19
  • 打赏
  • 举报
回复
数组s和数组ss代表的字符串没有空间存放空终结字符‘\0’
lunat 2017-01-19
  • 打赏
  • 举报
回复
除了刚才楼上讲过的strTxt越界问题,之外,还有一个问题可能是导致你这种情况的原因:

char sz[17] = {0};
//...
memset(sz,0x0,20);
请改为: memset(sz, 0x00, sizeof(sz));
ziyue007 2017-01-19
  • 打赏
  • 举报
回复
引用 4 楼 cfjtaishan 的回复:
sz length 14;strTxt length:4104 strTxt长度越界了
我在Ubuntu上运行的时候也知道这个样子的结果,但是放到ARM板上的Linux系统上运行不到越界 程序再ARM板上的Linux系统下边运行的时候,第二次执行到main函数第54行strcat这个函数的时候,会把strTXT里边第一次放进去的字符串都覆盖掉,printf显示出来的字符串还是16个字节大小,上一次拼进去的字符串被覆盖掉了 我这么描述能描述清楚吗? 程序不会执行到数组越界,因为strTxt在使用strlen测试大小的时候始终都是16个字节
ziyue007 2017-01-19
  • 打赏
  • 举报
回复
引用 3 楼 adlay 的回复:
if(strlen(strTxt)<=4096): 在 strlen(strTxt)==4096 的时候, 再执行你下面的语句访问就越界了
不是,我的意思是程序再ARM板上的Linux系统下边运行的时候,第二次执行到main函数第54行strcat这个函数的时候,会把strTXT里边第一次放进去的字符串都覆盖掉,printf显示出来的字符串还是16个字节大小,上一次拼进去的字符串被覆盖掉了 我这么描述能描述清楚吗? 程序不会执行到数组越界,因为strTxt在使用strlen测试大小的时候始终都是16个字节

70,024

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧