簡體   English   中英

可以更改C非指針類型的內存地址嗎?

[英]Can you change the memory address of a C non-pointer type?

我一直在實現一些C數據結構,以便完全理解它們。

這是我對字符串鏈接列表的定義:

typedef struct str_linked_list {

   const char*                 data;
   struct str_linked_list*     next;

} str_linked_list;

這是刪除列表的第n個元素的函數的實現:

void str_remove_at(str_linked_list* list, int index) {
    // Invalid index case
    if (index < 0) {

        fprintf(stderr, "Error, array index < 0\n");
        return;

    } 

    str_linked_list* to_delete; // Always gonna need this
    // Delete head case
    if ( index == 0 ) {

        to_delete = list;
        // If this node is not the last one save the reference to the remaining ones
        if ( to_delete->next != NULL )
            list = list->next;

        //free(to_delete);
        return;

    }
    // General case
    int i = 0;

    str_linked_list* buf = list;

    for (i = 0; i != index-1; i++) {

        if (buf->next != NULL){

            buf = buf->next;

        } else {

            fprintf(stderr, "The list is not that long, aborting operation");
            return;

        }

    }

    to_delete = buf->next;

    if ( to_delete->next != NULL )
        buf->next = to_delete->next;

    free(to_delete);

}

到目前為止,它運行良好,但是我相信我所說的方式無法刪除該頭部,這就是為什么注釋free(head)的原因。 我已經使用以下代碼測試了此代碼:

#include "LinkedList.h"

int main() {

    str_linked_list l;
    l.data = "Hello, World";
    l.next = NULL;

    str_remove_at(&l, 1); 


    str_print(&l);

    printf("\n\n");

    str_remove_at(&l, 0);
    str_print(&l);

    return 0;
}

我有點弄清楚了,如果不將列表初始化為指針,則很難更改存儲該變量的內存地址。我是否必須重新編碼lib才能將列表初始化為指針?如何將變量的存儲位置分配給另一個地址?

總結一切,我可以這樣更改“ i”的值嗎?

#include "stdlib.h"

void change_value(int* i) {
   int* new_alloc = malloc(sizeof(int));
   *new_alloc = 1;
    i = new_alloc;
}

int main() {
    int i = 0;
    change_value(&i);
    return 0;
}

您可以通過幾種方法來解決刪除列表標題的問題:

A)將列表作為**list傳遞,允許您從函數內部分配頭,即,調用為str_remove_at(&list, i)並使用*list代替函數內部的list

B)從函數返回列表的開頭,在這種情況下,調用者應執行list = str_remove_at(list, i)

C)要求您的列表的頭部有一個“ sentinel”元素,該元素永遠不會刪除,並且實際列表從head->next開始。 這“浪費”了一個列表節點,但是當實際的第一個元素不再是特殊情況時,也可以簡化其他操作。 (如果您有一個雙向鏈接列表,這樣做的好處將會增加。)

D)不用傳遞指向列表中節點的指針,而是使用單獨的str_list_nodestr_linked_list ,其中str_list_node是您當前的struct其中包含datanext ,而str_linked_list具有str_list_node *head 然后,當您傳遞str_linked_list *list您可以更改list->head而不必更改list本身。 (此解決方案可以擴展為具有其他優點,例如能夠存儲str_list_node *tail以附加O(1)。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM