【发布时间】:2015-07-28 05:57:37
【问题描述】:
我有一个令人沮丧的问题,我找不到答案。
我有这个功能:
// Append character to the end of a string
void str_AppendChar(char* s, const char* ch)
{
// +2 because of 2x '\0'
char* buff = malloc(strlen(s)+strlen(ch)+2);
memset(buff, 0, sizeof(buff));
// Copy the whole string in buff
strcpy(buff, s);
// Append ch at the end of buff
int len = strlen(buff);
strcpy(buff+len, ch);
// Set end of the string
*(buff+strlen(buff)-3) = '\0';
strcpy(s, buff);
free(buff);
}
由于某种原因,我的程序最后尝试执行两次 free 。
我使用 AppendChar() 的代码是:(有点难看但请忍耐)
void it_GatherCmd(cmd_Details* lineptr[], char* cmd)
{
// Used to count number of rows in lineptr
int nlines;
Detailptr p;
char ch;
char* word = (char*)malloc(sizeof(char)+256);
memset(word, 0, sizeof(word));
nlines = 0;
while ((ch = *cmd++) != '\n')
{
if (ch != ' ' && ch != '\0' )
str_AppendChar(word, &ch);
else
{
int type = dict_CheckWord(word);
if (type != -1)
{
p = it_CopyInfo(word, type);
lineptr[nlines++] = p;
}
memset(word, 0, sizeof(word));
}
}
//EDIT*
free(word);
}
还有我的主要:
int main()
{
cmd_Details* arrCmd[MAXLINES];
char* str = "just some string";
it_GatherCmd(arrCmd, str);
printf("%s", str);
return 0;
}
AppendChar() 在我创建它_GetCharCmd() 并在那里使用它之前一直没有问题。我在这上面花了大约 3 个小时,但我找不到问题所在。在互联网上进行了一些搜索,但我发现的内容与我的问题并不完全相关。
【问题讨论】:
-
我很确定
memset在这两个函数中的调用不会像你期望的那样工作;sizeof(buf)这里将是sizeof(char*),而不是数组的长度。 -
对于
strcpy(s, buff);,我认为不会有问题,因为要使用的数据很可能永远不会到达sizeof(char)+256。但我会记住稍后对其进行优化。memset用于清除分配的内存中的数据,以便以后可以重用。工作完成后内存被释放。 -
整个过程非常无效。当您所做的只是将一个字符附加到一个单词时,为什么还要在本地分配和释放内存?我认为(除了将所需的数据存储在命令结构中),您根本不需要动态分配。例如,最好使用
char buf[256]在 steck 上创建一个 256 字节的缓冲区作为自动内存,然后您就完成了。 -
不一定是具体问题的原因,但在
str_AppendChar()中,第二个参数被视为字符串(与strlen()和strcpy()一起使用),而它实际上只是指向一个字符,而不是以空字符结尾的字符序列。所以它会尝试访问字符后面的随机内存,直到它碰巧找到的下一个 null。 -
这里
strcpy(buff+len, ch);一个简单的strcat(buff, ch);就可以了。
标签: c pointers char free double-free