Fedora 17 64 位上的 C GCC 变量数据损坏
Variable data corruption with C GCC on Fedora 17 64 bit
我正在创建一个临时缓冲区并使用 sprintf 将一个字符串复制到该缓冲区。然后我调用函数 analyzeRecordForPGDBOperation 将缓冲区作为参数传递。我使用 | 解析带有 strtok 的字符串作为分隔符。我看到一个奇怪的问题,codesite 的值后来被损坏,即使它在 switch case 2 中正确打印。当我在 case 3 和 case 4 中打印时,codesite 的值不正确。
我试图在 gdb 中使用 codesite 变量上的 watch 查看它的共振,我得到以下输出,但我不确定为什么会出现这个问题。
[root@pe1800xs64 trunk]# uname -r
3.9.10-100.fc17.x86_64
"Output from GDB:"
Old value = "71663138", '[=12=]0'
New value = "[=12=]01663130", '[=12=]0'
0x00000038f30939ee in __strcpy_sse2_unaligned () from /lib64/libc.so.6
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main()
{
char tmp[256];
sprintf(tmp, "%s", "99|71663138|316DEA40C62D6BA40B3C0AA2FE06C457|1442319758");
analyzeRecordForPGDBOperation(tmp);
return 0;
}
void analyzeRecordForPGDBOperation(char *data)
{
char tempBuff[256] = {'[=10=]',};
char park[16] = {'[=10=]',};
char codesite[16] = {'[=10=]',};
char key[24] = {'[=10=]',};
char timestamp[16] = {'[=10=]',};
int caseVal = 0;
sprintf(tempBuff, "%s", data);
char *p = strtok(tempBuff,"|");
for (; p != NULL; p = strtok(NULL, "|"))
{
caseVal++;
switch(caseVal)
{
case 1:
sprintf(park, "%s", p);
break;
case 2:
sprintf(codesite, "%s", p);
//Value of codesite is printed correctly here
printf("\nCodesite: %s\n", codesite);
break;
case 3:
sprintf(key, "%s", p);
//Value of codesite is corrupted
printf("\nCodesite Case 3: %s\n", codesite);
break;
case 4:
sprintf(timestamp, "%s", p);
//Value of codesite is corrupted
printf("\nCodesite case 4: %s\n", codesite);
break;
default:
break;
}
}
}
输出:
[root@pe1800xs64 trunk]# ./a.out
analyzeRecordForPGDBOperation
Codesite: 71663138
Codesite Case 3:
Codesite case 4:
如果此 "316DEA40C62D6BA40B3C0AA2FE06C457"
是您需要在 case 3
上复制的值,则目标缓冲区 key
不够大。
这会触发未定义的行为,这就是为什么您之后会在 codesite
中看到奇怪的结果,即使您没有直接修改它。
我分配的缓冲区大小较小。缓冲区大小为 24,而我正在尝试向其中复制 33 个字符。因此,内存已损坏。
有了新尺寸,问题就解决了。
char codesite[16] = {'\0',};
字符键[35] = {'\0',};
感谢帮助
我正在创建一个临时缓冲区并使用 sprintf 将一个字符串复制到该缓冲区。然后我调用函数 analyzeRecordForPGDBOperation 将缓冲区作为参数传递。我使用 | 解析带有 strtok 的字符串作为分隔符。我看到一个奇怪的问题,codesite 的值后来被损坏,即使它在 switch case 2 中正确打印。当我在 case 3 和 case 4 中打印时,codesite 的值不正确。
我试图在 gdb 中使用 codesite 变量上的 watch 查看它的共振,我得到以下输出,但我不确定为什么会出现这个问题。
[root@pe1800xs64 trunk]# uname -r 3.9.10-100.fc17.x86_64
"Output from GDB:"
Old value = "71663138", '[=12=]0' New value = "[=12=]01663130", '[=12=]0'
0x00000038f30939ee in __strcpy_sse2_unaligned () from /lib64/libc.so.6
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main()
{
char tmp[256];
sprintf(tmp, "%s", "99|71663138|316DEA40C62D6BA40B3C0AA2FE06C457|1442319758");
analyzeRecordForPGDBOperation(tmp);
return 0;
}
void analyzeRecordForPGDBOperation(char *data)
{
char tempBuff[256] = {'[=10=]',};
char park[16] = {'[=10=]',};
char codesite[16] = {'[=10=]',};
char key[24] = {'[=10=]',};
char timestamp[16] = {'[=10=]',};
int caseVal = 0;
sprintf(tempBuff, "%s", data);
char *p = strtok(tempBuff,"|");
for (; p != NULL; p = strtok(NULL, "|"))
{
caseVal++;
switch(caseVal)
{
case 1:
sprintf(park, "%s", p);
break;
case 2:
sprintf(codesite, "%s", p);
//Value of codesite is printed correctly here
printf("\nCodesite: %s\n", codesite);
break;
case 3:
sprintf(key, "%s", p);
//Value of codesite is corrupted
printf("\nCodesite Case 3: %s\n", codesite);
break;
case 4:
sprintf(timestamp, "%s", p);
//Value of codesite is corrupted
printf("\nCodesite case 4: %s\n", codesite);
break;
default:
break;
}
}
}
输出:
[root@pe1800xs64 trunk]# ./a.out
analyzeRecordForPGDBOperation
Codesite: 71663138
Codesite Case 3:
Codesite case 4:
如果此 "316DEA40C62D6BA40B3C0AA2FE06C457"
是您需要在 case 3
上复制的值,则目标缓冲区 key
不够大。
这会触发未定义的行为,这就是为什么您之后会在 codesite
中看到奇怪的结果,即使您没有直接修改它。
我分配的缓冲区大小较小。缓冲区大小为 24,而我正在尝试向其中复制 33 个字符。因此,内存已损坏。 有了新尺寸,问题就解决了。
char codesite[16] = {'\0',}; 字符键[35] = {'\0',};
感谢帮助