我做了一个列表来做一些数据处理,我遇到了一个我找不到原因的问题,对我来说,我的代码似乎是正确的但有问题。
我要做的是以下内容: 我有一个包含x元素的列表。我想在列表中添加一个元素p,然后获取每个x元素,将p添加到它们代表的字符串,并将它们添加到列表中。 (列表本身效果很好,只是导致麻烦的操作)。
问题在于,当我这样做并且当我尝试显示列表时,第一个x + p元素显示得很好,但在我看到一些与输入无关的奇怪字符之后。
以下是我使用的功能:
void addFirst(struct list *l, char *key)
{
struct node *x = createNode(key) ;
if (l->size == 0)
{
l->first = x;
}
else
{
x->next = l->first;
l->first = x;
}
l->size++;
return;
}
void showList(struct list* l)
{
struct node *p=l->first;
while (p!=NULL)
{
printf("%s \n",p->key);
p=p->next;
}
return;
}
void copyPlus(struct list* l,char *ch)
{
struct node *p=l->first;
addFirst(l,ch);
while (p!=NULL)
{
int len1=strlen(p->key);
char cat[len1+2];
strcpy(cat,p->key);
strcat(cat,ch);
cat[len1+1] = '\0';
printf("[%s] \n",cat);
addFirst(l,cat);
printf("{%s} \n",l->first->key);
p=p->next;
}
return;
}
int main()
{
struct list *A=createList();
addFirst(A,"1");
addFirst(A,"2");
addFirst(A,"4");
copyPlus(A,"3");
printf("=%s= \n",A->first->key); //this one works!
printf("=%s= \n",A->first->next->key);
printf("=%s= \n",A->first->next->next->key);
showList(A);
deleteList(A);
}
我跳过了无关紧要的东西,这是一个经典列表。
节点的定义方式如下:
struct node
{
struct node *next;
char *key;
};
经过进一步的调查后,似乎该过程正常工作(copyPlus中的两个// printf以他们应该的方式工作)。最后// printf没有显示任何内容,即使我做了A-> first-> next-> next-> next。 它显示3如果我做A-> first-> next-> next-> next-> next。
我真的不明白,它开始让我紧张,代码很简单,我仍然没有看到错误。
有人可以帮助我吗?感谢。
答案 0 :(得分:2)
好的,所以strcat
为字符串添加一个终止零,你需要多一个字符的空间。 strlen
将给你1,你将分配一个大小为2的字符数组。这还不够 - 你需要至少3为第一个字符,第二个字符和终止零。那仍然很危险,因为你不知道第二根弦的长度。因此,最佳解决方案为char* cat = malloc(len1 + len2 + 1)
。
当前的问题是char cat[len1+2];
正在堆栈上分配空间(这是本地函数变量所在的位置)。你基本上保持一个指向堆栈框架内部地址的指针,该函数在函数完成后被销毁。第一个值有效,因为这是你的最后一个函数调用,但仍然没有人决定覆盖这个内存(但任何都可以自由地执行此操作)。使用malloc()
分配将在堆上分配,并且在您明确调用free
之前,该值将可用。
修改输出后:
[43]
{43}
[23]
{23}
[13]
{13}
=13=
=23=
=43=
13 23 43 3 4 2 1
可以在http://pastebin.com/xNzyLQ2N找到C ++解决方案。