C 中的列表和字符串问题

发布于 2024-11-05 02:37:54 字数 1806 浏览 0 评论 0原文

我列出了一个列表来进行一些数据处理,但我遇到了一个问题,我找不到原因,对我来说,我的代码似乎是正确的,但存在问题。

我想做的是: 我有一个包含 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 按其应有的方式工作)。即使我执行 A->first->next->next->next,最后一个 //printf 也不会显示任何内容。 如果我执行A->第一个->下一个->下一个->下一个->下一个,它会显示3。

我真的不明白,它开始让我感到不安,代码简单而简短,但我仍然没有看到错误。

有人可以帮助我吗?谢谢。

I made a list to do some data treatment and I'm having an issue that I don't find the cause, for me my code seems right but there are issues.

What I'm trying to do is the following :
I have a list that contains x elements. I want to add an element p in the list then take every x element, add p to the string they represent, and add them to the list. (the list by itself works great it's just that operation that causes troubles).

The problem is that when I do that and when I try to display the list the first x+p elements are displayed well, but after I see some strange characters that have nothing to do with the inputs.

Here are the functions I use :

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);
}

I skipped the irrelevant stuffs, it's a classic list.

Node is defined that way :

struct node
{
  struct node *next;
  char *key;
};

After further ivestigation it appears that the process is working correctly (the two //printf in copyPlus work the way they should). And the last //printf doesn't display anything, even if I do A->first->next->next->next.
It shows 3 if I do A->first->next->next->next->next.

I really don't understand and it's starting to get on my nerves, the code is simple and short and I'm still not seeing the mistake.

Could someone help me? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里兽 2024-11-12 02:37:54

好的,strcat 向字符串添加了一个终止零,您需要再留出一个字符的空间。 strlen 将为您提供 1,您将分配一个大小为 2 的 char 数组。这还不够 - 您至少需要 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

C++ 解决方案可以在 http://pastebin.com/xNzyLQ2N 找到。

Ok, so strcat adds a terminating zero to the string, you need space for one more char. strlen will give you 1, you will allocate a char array with size 2. That's not enough - you need at least 3 for the first char, second char and terminating zero. That's still dangerous, as you don't know the length of the second string. The best solution is thus char* cat = malloc(len1 + len2 + 1).

The current problem is that char cat[len1+2]; is allocating space on the stack (that's where local function variables reside). You're basically keeping a pointer to an address inside of a stack frame, which gets destroyed after the function has finished. The first value works, because this was your last function call and still noone has decided to overwrite this memory (but anyone is free to do so). Allocating with malloc() will allocate on the heap and the value will be available until you explicitly call free.

After modifications output is:

[43]
{43}
[23]
{23}
[13]
{13}
=13=
=23=
=43=
13 23 43 3 4 2 1

A C++ solution can be found at http://pastebin.com/xNzyLQ2N .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文