程序的目的是做一个xml解析的工作。
部分代码如下:
#define BUFLEN 10240
typedef struct buffer_t//需要操作的结构体
{
char *buf;
Bcsarray *bcsay;
int bufnum;
struct buffer_t *next;
}databuf;
databuf *buf, *bufs;//buf为链表头,bufs为操作时的游动指针
void readxml(void *arg);//第一个线程,已经正确初始化了buf链表,每块中buf->buf的大小都为BUFLEN+1;问题不在这个函数中,故不再列出
void division(void *arg)//有两个重要位置我标记了出来,后面有说明
{
bufs = buf;
while (bufs != NULL)
{
int i = 0, j = 0;
int n = 0;
if (bufs->buf[i] == '<')
{
j = i;
j++;
switch (bufs->buf[j])
{
case '/':
{
while (1)
{
j++;
if (bufs->buf[j] == 0)
{
if (bufs->next == NULL)
{
bufs->bcsay->bcs[n].bufnum = bufs->bufnum;
bufs->bcsay->bcs[n].bufpos = i;
bufs->bcsay->bcs[n].bt = Etag_start;
i = j;
break;
}
else
{
char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1));
**strcpy(e, bufs->next->buf);//这里报错(2号位置)**
strcpy(bufs->next->buf, bufs->buf + i);
strcat(bufs->next->buf, e);
bufs->buf[i] = 0;
free(e);
break;
}
}
if (bufs->buf[j] == '<')
{
bufs->bcsay->bcs[n].bufnum = bufs->bufnum;
bufs->bcsay->bcs[n].bufpos = i;
bufs->bcsay->bcs[n].bt = Etag_start;
n++;
i = j;
break;
}
}
}; break;
case '?':
{
while (1)
{
j++;
if (bufs->buf[j] == 0)
{
char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1));
strcpy(e, bufs->next->buf);
strcpy(bufs->next->buf, bufs->buf + i);
strcat(bufs->next->buf, e);
bufs->buf[i] = 0;
free(e);
break;
}
if (bufs->buf[j] == '>')
{
if (bufs->buf[j - 1] == '?')
{
bufs->bcsay->bcs[n].bufnum = bufs->bufnum;
bufs->bcsay->bcs[n].bufpos = i;
bufs->bcsay->bcs[n].bt = PI_start;
n++;
j++;
i = j;
break;
}
}
}
}; break;
case '!':
{
while (1)
{
j++;
if (bufs->buf[j] == 0)
{
char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1));
strcpy(e, bufs->next->buf);
strcpy(bufs->next->buf, bufs->buf + i);
strcat(bufs->next->buf, e);
bufs->buf[i] = 0;
free(e);
break;
}
if (bufs->buf[j] == '>')
{
if (bufs->buf[j - 1] == '-'&&bufs->buf[j - 2] == '-')
{
bufs->bcsay->bcs[n].bufnum = bufs->bufnum;
bufs->bcsay->bcs[n].bufpos = i;
bufs->bcsay->bcs[n].bt = COMMENT_start;
n++;
j++;
i = j;
break;
}
else if (bufs->buf[j - 1] == ']'&&bufs->buf[j - 2] == ']')
{
bufs->bcsay->bcs[n].bufnum = bufs->bufnum;
bufs->bcsay->bcs[n].bufpos = i;
bufs->bcsay->bcs[n].bt = CDSECT_start;
n++;
j++;
i = j;
break;
}
}
}
}; break;
default:
{
while (1)
{
j++;
if (bufs->buf[j] == 0)
{
if (bufs->next == NULL)
{
bufs->bcsay->bcs[n].bufnum = bufs->bufnum;
bufs->bcsay->bcs[n].bufpos = i;
int k = 1;
while (1)
{
if (bufs->buf[j - k] == '>')
{
if (bufs->buf[j - k - 1] == '/')
bufs->bcsay->bcs[n].bt = Etag_start;
else
bufs->bcsay->bcs[n].bt = Stag_start;
break;
}
k++;
}
i = j;
}
else
{
char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1));
**strcpy(e, bufs->next->buf);//这里正常运行(1号位置)**
strcpy(bufs->next->buf, bufs->buf + i);
strcat(bufs->next->buf, e);
bufs->buf[i] = 0;
free(e);
break;
}
}
if (bufs->buf[j] == '<')
{
bufs->bcsay->bcs[n].bufnum = bufs->bufnum;
bufs->bcsay->bcs[n].bufpos = i;
int k = 1;
while (1)
{
if (bufs->buf[j - k] == '>')
{
if (bufs->buf[j - k - 1] == '/')
bufs->bcsay->bcs[n].bt = Etag_start;
else
bufs->bcsay->bcs[n].bt = Stag_start;
break;
}
k++;
}
n++;
i = j;
break;
}
}
}; break;
}
}
else
{
i++;
}
}
bufs = bufs->next;
}
}
两个线程我已经做了处理,暂时是串行执行的,互不影响。division这个线程,第一次(1号位置)和第二次(二号位置)运行的分支我已标注出,分支中的逻辑完全相同,但是只有第一次可以运行通过,第二次就不行了。循环会有很多次,但现在只能运行到第二次结尾。本来想删掉一部分无关代码,但害怕出问题,敬请谅解。
以上代码,我在windows下用vs2015跑过。把两个线程串行地写在一个函数中,正常运行。但是在Linux下用多线程,就会出现以上问题,strcpy函数位置出错。
后来经过调试发现,是在二号位置中,bufs->next->buf的问题。当我在gdb中调试到这里时,用“p bufs->next->buf”输出内容时,就出现Cannot access memory at address的错误。但是我访问数据结构中的其他项,比如
“p bufs->next->bufnum”,输出正常。并且在上一个线程中,一切正常。
求大神指点。