簡體   English   中英

C ++在另一個函數中將指針分配給動態內存中的數組

[英]C++ Reallocating pointer to array in dynamic memory in a different function

我剛剛在C ++中完成了有關指針和動態內存的模塊,並試圖完成個人任務,以便我可以練習這些概念。 該程序管理名稱的字符串數組。 我為自己設置的目標是將列表存儲在堆中(以練習使用“ new”),並在輸入新名稱時動態調整列表的大小。

免責聲明:我意識到使用向量很容易做到這一點,並且在為此苦苦掙扎數小時之后,我重新編寫了原始代碼,將向量毫無問題地用於列表。 但是,我想了解我對指針如何工作的理解被打破了。

我的程序存在以下問題:我將name數組初始化為具有零個元素,並且具有添加用於處理動態大小的名稱的函數。 首次調用時,似乎可以正確調整數組的大小,並在新數組中添加一個新名稱。 在函數內添加一個名稱,我可以打印新數組的內容。 我還可以將舊的數組指針重新分配給堆上新數組的地址。 但是,當我在列表中添加名稱后從main調用打印功能時,列表中沒有名稱。 根據我的理解,由於我使用的是指針,因此我應該直接更新值,因此在add name函數終止后,這些值應該保持不變。 另外,如果我嘗試添加第二個名稱,程序將崩潰。 我在處理內存時出了什么問題?

我搜索了很多,找到的最接近的分辨率是這篇文章:

如何制作一個動態大小的數組? 動態數組的一般用法(也許也有指針)?

我根據自己的理解修改了代碼,但仍然無法正常工作。

    #include <stdio.h>
    #include <vector>
    #include <iostream>

    using namespace std;

    void add_name_to_list(string * my_list, size_t * list_size);
    string get_name();
    void print_names(const string *const my_list, const size_t *const list_size);

    int main()
    {
        string *name_list_ptr {nullptr};
        name_list_ptr = new string [0];
        size_t name_list_size{0};
        size_t *name_list_size_ptr {&name_list_size};

        print_names(name_list_ptr, name_list_size_ptr);
        add_name_to_list(name_list_ptr, name_list_size_ptr);
        print_names(name_list_ptr, name_list_size_ptr);
        return 0;
    }

    void add_name_to_list (string * my_list, size_t *list_size)
    {
        string new_name{get_name()};
        string *new_string_ptr{nullptr};
            new_string_ptr = new string [*list_size+1];
            // copy existing list into new list
            cout << "List size is " << *list_size << " so *list size == 0 is " << (*list_size == 0) << endl;
            if(*list_size == 0)
            {
                new_string_ptr[0] = new_name;
                *list_size = *list_size +1;
                cout << new_string_ptr[0] << " has been added to position " << *list_size << endl;

            }
            else
            {
                print_names(my_list, list_size);
                for(size_t i{0}; i < *list_size; i++)
                {
                    cout << "At position " << i << " original list is " << my_list[i] << endl;
                    new_string_ptr[i] = my_list[i];
                    cout << "The name " << new_string_ptr[i] << " has been added to position " << i << " of the new list" << endl;
                }
                new_string_ptr[*list_size - 1] = new_name;
                *list_size = *list_size + 1;
            }
            print_names(new_string_ptr, list_size);

            string *temp_ptr{nullptr};
            temp_ptr = new string [*list_size-1];
            cout << "temp ptr is " << temp_ptr << " and my list is " << my_list << endl;
            temp_ptr = my_list;
            cout << "temp ptr is " << temp_ptr << " and my list is " << my_list << endl;
            my_list = new_string_ptr;
            delete [] temp_ptr;
            new_string_ptr = nullptr;
            print_names(my_list, list_size);
    }

    string get_name()
    {
        cin.sync();
        cin.clear();
        string new_name{};
        cout << "\nEnter the full name: ";
        getline(cin, new_name);
        cin.sync();
        cin.clear();
        if(new_name.size() <= 1)
            return "0";
        else
            return new_name;    
    }

    void print_names(const string *const my_list, const size_t *const list_size)
    {
        if(*list_size == 0)
            cout << "The list is empty" << endl;
        else
            for(size_t j{0}; j < *list_size; j++)
                    cout << j << ". " << my_list[j] << endl;
    }

根據從搜索中學到的知識,我嘗試了一種變體:

    cout << "temp ptr is " << temp_ptr << " and my list is " << my_list << endl;
    //my_list = new_string_ptr;
    //delete [] temp_ptr;
    //new_string_ptr = nullptr;

    delete [] my_list;
    my_list = new string[*list_size];
    my_list = new_string_ptr;
    print_names(my_list, list_size);

不幸的是結果是一樣的。

在不檢查實現邏輯的情況下,您的列表不會更新,因為您正在分配my_list = new_string_ptr; 但是您的函數接收到了void add_name_to_list (string * my_list, size_t *list_size)

當您剛接觸C ++世界時,請讓我清楚地解釋一下:list_size是指向size_t的指針,因此,如果您修改指向的內存,則更改將繼續存在,但是如果您修改指針本身,則不會。

list_size = new size_t; // This change doesn't persist
list_size++; // This change doesn't persist

*list_size++; // This change persists and the value of pointed memory was increased.

my_list發生的情況完全相同,您嘗試修改指針本身,而不是指向的內存。

因此,您應該使用:

void add_name_to_list (string * &my_list, size_t *list_size)

也許您更喜歡

void add_name_to_list (string ** my_list, size_t *list_size)
[...]
*my_list = new_string_ptr;

希望這可以幫助

暫無
暫無

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

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