C中链表的总大小

时间:2010-03-05 21:03:13

标签: c linked-list

好吧......我对CS数据结构的介绍非常生疏,我需要在这里提出这个问题。

我有一个链接列表,其结构是:

struct Data_Struct {
    char *Name;
    char *Task;
    char *Pos;
    struct Data_Struct *Next;
};
typedef struct Data_Struct MyData;

现在,在我的应用程序的某个时刻,我用数据填充了列表。

问题是,如何获取存储在那里的数据的总大小?有多少个字符?像

这样的东西
sizeof(MyData);

这将返回列表中存储的信息的大小。

代码表示赞赏。

谢谢!

修改: 不幸的是,这不是功课。我在20多年前完成了学业,坦率地说,我从来没有在任何事情上使用链接列表。我只是不记得了。 我正在做的是迭代列表并获取每个元素的strlen()并将其保持在全局大小但我想知道是否有更好的方法。

和NO,我不需要链接的大小(节点的数量),我只想知道那里存储了多少个字符。

感谢

7 个答案:

答案 0 :(得分:5)

你通常会查看列表,直到你到达尾项,同时计数,代码应该是这样的:

int listLength(struct Data_Struct* item)
{
  struct Data_Struct* cur = item;
  int size = 0;

  while (cur != null)
  {
    ++size;
    cur = cur->Next;
  }

  return size;
}

请注意,此操作的复杂性与列表的大小呈线性关系,因此它是 O(n),效率非常低。您可以在某处存储大小并使用列表插入和删除进行更新,以避免任何开销,并且能够在恒定时间内计算它 O(1)

修改 没有注意到你想要将整个数据的大小包含在列表中。在你的情况下,你可以保持用于计算长度的相同方法,但是为每个元素添加 1 ,你应该添加字符串的总长度:

size += strlen(Name)+strlen(Task)+strlen(Pos);

请注意,由于列表元素中的数据char*类型Data_Struct的有效大小只有4个指针,因此您需要使用strlen等支持函数,否则你无法获得字符串的真实维度。

有什么区别?

sizeof(Data_Struct) == 16

因为Data_Struct类型包含4个指针,3个用于指向char的指针,1个用于列表中的下一个元素

sizeof(Name) == sizeof(Task) == sizeof(Pos) == 4

因为这些变量属于指向char 的指针,所以它们是指针,没有具体的值,通常是4个字节(我假设是32位架构)

strlen(Name) == length in chars of the string

因为该函数完全用于计算字符串的长度。

答案 1 :(得分:3)

好吧,您可以遍历列表来轻松计算计数。显然,总内存将等于项目数乘以每个项目的大小(sizeof(Data_Struct))。

当然,这将是链表本身的大小,不包括为字符串分配的内存。指针没有任何关于它所引用的已分配内存量的信息,因此严格来说,只能通过查看链接列表来计算直接分配的总内存量。此外,您需要跟踪链接列表中可能存在重复的指针。也就是说,假设所有指针都是唯一的,您可以通过在遍历列表时对每个指针上的strlen调用的返回值求和来计算每个项中的字符数(这应该非常简单)。 p>

答案 2 :(得分:3)

为节点分配内存(使用malloc)后,您应该可以执行sizeof(yourDataType)。因此,要获取链表的总大小,请遍历列表并获取节点数:

Total Size Of Linked List = SizeOf(One Node) * Count Of Nodes

例如:

int getCountOfList()
{
 Node* temp = head; //assign a temp node to the head of the list
 int count=0;

 while(temp) {
  count++;
  temp = temp->next; //move to next node
 }
 return count;
}

然后你取这个数并乘以大小:

size = getCountOfList * sizeof(mydatatype);

这将为您提供实际链表的大小,但由于链表节点具有指针元素,因此指针元素本身也可以分配内存。这需要考虑......

例如,节点中的其中一个char *元素可能会占用更多空间并占用一些内存。

如果您确实需要列表的整个大小,包括所有其他char *指针的已分配元素,例如,您只需:

1)遍历列表并查看每个节点

2)对于每个节点,检查每个节点的元素是否指向任何其他分配(for 实例char *数据可以分配50个字符来存储)。如果它不为null,则获得字符串的长度+ 1(用于终止char),然后将其乘以sizeof(char)(对于此示例)

3)您为每个节点执行此操作并存储该大小,然后移至下一个节点

4)你为每个节点取所有这些char *(在这种情况下)的SUM,并为整个列表累积。

5)完成后,只需添加此总和,即可获得所有节点的大小。

然后总大小变为:

SizeOfAllNode + (SizeOf(dataType) * CountOfNodes)

答案 3 :(得分:1)

在添加或删除节点时保持运行计数。这样,您不必走列表,每次想要计数时总结每个节点。只需参考您的最新价值。

答案 4 :(得分:0)

要计算列表本身的大小,只需取sizeof(MyData)并乘以节点数。

如果要在列表中包含字符串数据的大小,可以将字符串使用的内存计算为(strlen(str) + 1) * sizeof(char) - 当然假设字符串已分配到正确的大小。

答案 5 :(得分:0)

如果你需要不止一次地获取数据的大小,那么在向列表中添加元素时跟踪它会更明智,但是用来计算暴力的代码非常简单。

 size_t cb = 0;
 int    cItems = 0;
 struct Data_Struct * pnext = &MyData;
 while (pnext)
    {
    if (pnext->Name)
       cb += (strlen(pnext->Name)+1) * sizeof(char);
    if (pnext->Task)
       cb += (strlen(pnext->Task)+1) * sizeof(char);
    if (pnext->Pos)
       cb += (strlen(pnext->Pos)+1) * sizeof(char);
    ++cItems;
    pnext = pnext->Next;
    }

 // cb has the total size of the strings, now add the size of the data structs
 cb += sizeof(struct Data_Struct) * cItems;

答案 6 :(得分:0)

您可以遍历列表中的所有成员并累积名称,任务和位置上的字符数。

但是,如果您要多次这样做,我会在填充节点时存储每个字段的字符数,而不是一次又一次地计算它们。

因此,您的结构将定义如下:

struct Data_Struct {
    char *Name;
    int   NameCount;

    char *Task;
    int   TaskCount;

    char *Pos;
    int   PosCount;
    struct Data_Struct *Next;
};
typedef struct Data_Struct MyData;

并遍历列表可能类似于:

void getCharacterCount(struct Data_Struct* data, int* nameCount, int* taskCount, int* posCount)
{
  struct Data_Struct* auxData = data;
  int nc = tc = pc = 0;

  for (; auxData; auxData = auxData->Next())
  {
    nc += auxData->NameCount; 
    tc += auxData->TaskCount;
    pc += auxData->PosCount;
  }

  *nameCount = nc;
  *taskCount = tc;
  *posCount  = pc;
}