[英]C++ Reallocating pointer to array in dynamic memory in a different function
I have just done a module on pointers and dynamic memory in C++ and am attempting to complete a personal assignment so that I can practice the concepts. 我刚刚在C ++中完成了有关指针和动态内存的模块,并试图完成个人任务,以便我可以练习这些概念。 The program manages an array of strings that are names.
该程序管理名称的字符串数组。 The goal that I set for myself is that the list is stored in the heap (to practice using "new"), and the list is dynamically sized as new names are entered.
我为自己设置的目标是将列表存储在堆中(以练习使用“ new”),并在输入新名称时动态调整列表的大小。
Disclaimer: I realize that this is easily accomplished using vectors, and after struggling with this for hours I re-wrote my original code to use a vector for the list with no problems. 免责声明:我意识到使用向量很容易做到这一点,并且在为此苦苦挣扎数小时之后,我重新编写了原始代码,将向量毫无问题地用于列表。 However I want to learn where my understanding of how pointers work is broken.
但是,我想了解我对指针如何工作的理解被打破了。
The problem that I have with the program is this: I initialize the name array to have zero elements and have a function to add names that handles the dynamic sizing. 我的程序存在以下问题:我将name数组初始化为具有零个元素,并且具有添加用于处理动态大小的名称的函数。 When first called it seems to re-size the array correctly and add a new name to the the new array.
首次调用时,似乎可以正确调整数组的大小,并在新数组中添加一个新名称。 Within the function to add a name, I can print the contents of the new array.
在函数内添加一个名称,我可以打印新数组的内容。 I can also re-assign the old array pointer to the address of the new array on the heap.
我还可以将旧的数组指针重新分配给堆上新数组的地址。 However when I call the print function from main after adding a name to the list, the list does not contain a name.
但是,当我在列表中添加名称后从main调用打印功能时,列表中没有名称。 By my understanding, since I'm using pointers I should be updating values directly, so after the add name function terminates, the values should persist.
根据我的理解,由于我使用的是指针,因此我应该直接更新值,因此在add name函数终止后,这些值应该保持不变。 Also, if I attempt to add a second name the program crashes.
另外,如果我尝试添加第二个名称,程序将崩溃。 What am I doing wrong with the handling of memory?
我在处理内存时出了什么问题?
I've searched quite a bit and the closest that I can find for a resolution was this post: 我搜索了很多,找到的最接近的分辨率是这篇文章:
How to make an array with a dynamic size? 如何制作一个动态大小的数组? General usage of dynamic arrays (maybe pointers too)?
动态数组的一般用法(也许也有指针)?
I modified my code based on what I understand from that but it still doesn't work properly. 我根据自己的理解修改了代码,但仍然无法正常工作。
#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;
}
One variation that I've tried based on what I learned from searching is: 根据从搜索中学到的知识,我尝试了一种变体:
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);
Unfortunately the results are the same. 不幸的是结果是一样的。
Without checking the logic of the implementation, your list doesn't update because you are assigning my_list = new_string_ptr;
在不检查实现逻辑的情况下,您的列表不会更新,因为您正在分配
my_list = new_string_ptr;
but your function received void add_name_to_list (string * my_list, size_t *list_size)
. 但是您的函数接收到了
void add_name_to_list (string * my_list, size_t *list_size)
。
As you are newcomer to C++ world, let me explain clearly: list_size is a pointer to a size_t, so if you modify the pointed memory, the change will persist, but if you modify the pointer itself, it will not. 当您刚接触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.
With my_list
is happening exactly the same, you are trying to modify the pointer itself, not the pointed memory. 与
my_list
发生的情况完全相同,您尝试修改指针本身,而不是指向的内存。
So, you should use: 因此,您应该使用:
void add_name_to_list (string * &my_list, size_t *list_size)
Or maybe you are more confortable with 也许您更喜欢
void add_name_to_list (string ** my_list, size_t *list_size)
[...]
*my_list = new_string_ptr;
Hope this helps 希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.