C 中带指针和结构的链表

Linked List with Pointer and Struct in C

我尝试用 c 语言编写一个带有指针和结构的链表。在控制台上,我的小示例正在运行,但只要我想检查什么 valgrind returns,就会出现下面的输出。

我认为这有点像 越界 异常,但我不知道如何正确解释和解决它。

源代码:

int main(){
  struct node {
      int data;
      struct node *nextNode;
  };

  int counter = 10;
  struct node *nodeSpace;

  nodeSpace = (struct node *) malloc(counter * sizeof(struct node));
  struct node *base = nodeSpace;

  for(int i = 0; i < counter; i++){
      int offset = i * sizeof(struct node);
      struct node *currentNode;

      currentNode = base + offset;
      currentNode->data = i;

      if(i == counter-1)
          currentNode->nextNode = NULL;
      else
          currentNode->nextNode = base + (i+1)*sizeof(struct node);

      printf("Node (%i): Address: %p Data: %i Next: %p\n", 
             i, currentNode, currentNode->data, currentNode->nextNode);
   }
   return 0;
}

Valgrind:

Node (0): Address: 0x5203040 Data: 0 Next: 0x5203140
Node (1): Address: 0x5203140 Data: 1 Next: 0x5203240
Node (2): Address: 0x5203240 Data: 2 Next: 0x5203340
Node (3): Address: 0x5203340 Data: 3 Next: 0x5203440
Node (4): Address: 0x5203440 Data: 4 Next: 0x5203540
==23418== Invalid write of size 4
==23418==    at 0x4005DC: main (linkedList.c:18)
==23418==  Address 0x5203540 is 32 bytes before an unallocated block of size 4,192,896 in arena "client"
==23418== 

来自 valgrind 的错误出现在第

currentNode->data = i;

如果有人能帮助我,那就太好了,谢谢。

类型化指针算法将基础元素的步幅保留为地址计算的一部分。这是原因,给定一个非void类型的指针p

p[i]

*(p+i)

是同义词。

要查看元素宽度的自动使用,请考虑:

int ar[2];
int *p = ar;
int *q = p+1;

printf("p = %p\n", (const void*)p);
printf("q = %p\n", (const void*)q);

样本输出(变化)

p = 0x7fff5fbff9d0
q = 0x7fff5fbff9d4

请注意 int 的大小已经计算在内(在本例中为四个字节)。

就是说,您的代码简化为:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct node
    {
        int data;
        struct node *nextNode;
    };

    int counter = 10;
    struct node *nodeSpace = malloc(counter * sizeof(struct node));

    for(int i = 0; i < counter; i++)
    {
        struct node *currentNode = nodeSpace + i;
        currentNode->data = i;

        if(i == counter-1)
            currentNode->nextNode = NULL;
        else
            currentNode->nextNode = currentNode+1;

        printf("Node (%i): Address: %p Data: %i Next: %p\n",
               i, currentNode, currentNode->data, currentNode->nextNode);
    }

    free(nodeSpace);
    return 0;
}

输出(例子)

Node (0): Address: 0x1001053a0 Data: 0 Next: 0x1001053b0
Node (1): Address: 0x1001053b0 Data: 1 Next: 0x1001053c0
Node (2): Address: 0x1001053c0 Data: 2 Next: 0x1001053d0
Node (3): Address: 0x1001053d0 Data: 3 Next: 0x1001053e0
Node (4): Address: 0x1001053e0 Data: 4 Next: 0x1001053f0
Node (5): Address: 0x1001053f0 Data: 5 Next: 0x100105400
Node (6): Address: 0x100105400 Data: 6 Next: 0x100105410
Node (7): Address: 0x100105410 Data: 7 Next: 0x100105420
Node (8): Address: 0x100105420 Data: 8 Next: 0x100105430
Node (9): Address: 0x100105430 Data: 9 Next: 0x0