好吧......我对CS数据结构的介绍非常生疏,我需要在这里提出这个问题。
我有一个链接列表,其结构是:
struct Data_Struct {
char *Name;
char *Task;
char *Pos;
struct Data_Struct *Next;
};
typedef struct Data_Struct MyData;
现在,在我的应用程序的某个时刻,我用数据填充了列表。
问题是,如何获取存储在那里的数据的总大小?有多少个字符?像
这样的东西sizeof(MyData);
这将返回列表中存储的信息的大小。
代码表示赞赏。
谢谢!
修改: 不幸的是,这不是功课。我在20多年前完成了学业,坦率地说,我从来没有在任何事情上使用链接列表。我只是不记得了。 我正在做的是迭代列表并获取每个元素的strlen()并将其保持在全局大小但我想知道是否有更好的方法。
和NO,我不需要链接的大小(节点的数量),我只想知道那里存储了多少个字符。
感谢
答案 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;
}