【问题标题】:Malloc of pointers in structs + pointer arithmetic + free() + linkedList结构中指针的 Malloc + 指针算术 + free() + linkedList
【发布时间】:2016-07-30 15:53:08
【问题描述】:

我正在尝试实现一个链表数据结构,其中每个节点都有一个标识符键、一些可变长度的数据(malloc)和一个指向下一个节点的指针。现在我想拥有 3 个函数,分别是:将新节点设置到列表的前面,使用标识符键打印给定节点的值,并删除给定节点。

我对节点的结构如下:

struct node {
 char key[5];
 int* data;
 node* next;
};
struct node* headNode = NULL;

我对每个功能都有疑问。我将列出我拥有的功能代码并在下面询问有关该特定功能的问题:

我的 set 函数的代码:

void command_set (char key[], int val[], int numOfVal){
 struct node* temp = (node*)malloc(sizeof(node));
 strcpy(temp->key, key);
 temp->data = (int*)malloc(numOfVal*sizeof(int));
 *(temp->data) = *(val);
 temp->next = entry_head;
 entry_head = temp;
 return;
}

现在我有一个关于这个功能的问题:

1) 我存储数据的方法是否有效?即“temp->data = (int*)malloc(numOfValuessizeof(int));” + "(temp->data) = *(val);"。我要做的是动态分配一些内存,然后将给定的值作为我节点的数据存储在该内存中。


我的打印功能代码:

void printNode (char key[], int numOfVal){
 int i;
 struct node *currentNode = headNode;

 while(currentNode->next!=NULL){
     if(!strcmp(currentNode->key,key) ){
        for(i=0; i<numOfVal; i++){
            printf("%d ",*((currentNode->data)+i));
        }
        return;
    }
    currentNode = currentNode->next;
}

我有一个关于此功能的问题:

2) 节点的数据是一个整数列表,那么我打印出每个整数的方法真的有效吗?即“*((currentNode->data)+i)”。我想要做的是通过使用指针算术打印存储在数据下的所有整数。


我的删除功能代码:

void deleteNode (char key[]){
 struct node *currentNode = headNode;
 struct node *prevNode = headNode;
 while(currentNode->next!=NULL){
    if(!strcmp(currentNode->key,key) ){
            prevNode->next = currentNode->next;
            free(currentNode->data);
            free(currentNode->next);
            free(currentNode);
            return;
    }

    prevNode = currentNode;
    currentNode = currentNode->next;
 }

关于这个函数我有两个问题:

3) 我是否正确“删除”了节点?通过使用 free()。是这样的吗?

4) 这是删除后连接节点的方式吗?通过将 next 指针设置为另一个节点。

为了简单起见,请假设 malloc 不会返回 NULL。另请注意,我已经简化了我的实际代码,否则要发布的内容太多了,所以可能会有轻微的错误。您还可以假设 while 循环将始终有效(即不会出现 (currentNode->next==NULL) 的情况。这篇文章的重点是我关于做某事的方法是否正确的问题。

该程序的一个示例是:

-设置 ex1 2 3 4 5

-得到ex1

2 3 4 5

-设置 ab 32 112

-得到ab

32 112

提前致谢。

【问题讨论】:

  • prevNode-&gt;next = currentNode-&gt;next; 后跟 free(currentNode-&gt;next); 是可疑的。这意味着现在prevNode-&gt;next 指向已释放(无效)的内存。不过可能还有更多问题。
  • @MichaelWalz 嗯,但您不希望这种情况发生吗?由于该节点现在基本上不存在,所以不应该释放所有成员及其本身吗?所以我的思考过程是,我首先将前一个节点链接到下一个节点,现在链接已经形成,我删除与要删除的节点相关的所有内容。还是我应该只释放数据,然后将旧链接留在那里?不太确定我是否做对了。
  • 一旦使用free函数释放内存,它就无效了。肯定的。我认为你应该先实现一个简单的链表,有大量的代码和教程。
  • *(temp-&gt;data) = *(val); 也很可疑,这是怎么回事?您可能需要遍历 val 数组。
  • 而你的指针算术也不是必须的:*((currentNode-&gt;data)+i))很复杂,你可以简单写currentNode-&gt;data[i]。

标签: c pointers struct linked-list malloc


【解决方案1】:
strcpy(temp->key, key); 

就您的程序而言,这可能没问题,但您应该使用 strncpy(temp->key,key,5) 以确保安全。或者至少检查钥匙的长度以确保它适合。

*(temp->data) = *(val);

这仅设置数组中的第一个索引。你应该在这里使用 memcpy。

memcpy (temp->data,val, sizeof (int) * numOfVal);

您的 print 函数会打印第一个不匹配的元素。你的意思是反其道而行之?

您的删除功能可以做到这一点。它找到第一个不匹配的节点。

你也不想释放 currentNode->next;

【讨论】:

  • 完美! memcpy 正是我想要的。我没有意识到 *(temp->data) = *(val);只是复制第一个索引而不是整个数组。
猜你喜欢
  • 1970-01-01
  • 2016-07-05
  • 2013-05-09
  • 2014-11-13
  • 2012-06-04
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
  • 2020-07-22
相关资源
最近更新 更多