在 for 循环中创建的对象具有相同的地址
我正在尝试创建一个自己的列表类,它具有固定大小并且可以存储整数.仅用于学习目的.
I'm trying to make an own list-class which is of a fixed size and can store integers. Just for learning purposes.
这就是我的做法:我有一个名为 Item 的结构,它保存数据(要存储的整数)和指向列表中下一项的指针.当列表初始化时,我首先将 x 数量的空项添加到列表中.
This is how I do it: I have a struct called Item which holds the data (the integer to store), and a pointer to the next item in the list. When the list gets initialized I first add x amount of empty Items to the list.
迭代(n-1)中声明的item的地址存储在缓冲区中,因此迭代n中的item的地址可以设置为上一次迭代(n-1)中的item的下一个.这将所有项目相互链接.
The address of item declared in iteration (n-1) is stored in a buffer, so that the address of the item in iteration n, can be set as next for the item in the previous iteration (n-1). This to chain all items to each other.
并且第一项的地址也被保存,作为后面代码中整个列表的访问点.
And the address of the very first item is also saved, as the access point for the whole list later in the code.
但这并没有真正起作用;这是我的代码:
But it's not really working; this is my code:
#include <iostream>
class List {
public:
//Item-object needed to store
//elements
struct Item {
int data = 0;
Item* next = nullptr;
};
//Constructor
//creates a list of fixed size
List(int size) {
//Filling up with empty items
for (int i = 0; i < size; i++) {
Item item;
//Storing iterator in item (just for testing purposes)
item.data = i;
//If first item,
//store start-address
//set buffer to start address
if (i == 0)
this->start = &item;
//Setting current item as nextptr
//for previous item in buffer
if (i > 0)
this->buffer->next = &item;
//Storing current address in buffer
this->buffer = &item;
//Outputting address and value (just for testing purposes)
//std::cout << "Address: " << &item << " -> " << item.data << std::endl;
}
}
Item* getFirstItemAddress() {
return this->start;
}
private:
//Holding address of first item
Item* start = nullptr;
//Buffer holding temporary address
Item* buffer = nullptr;
};
int main() {
List list(5);
//Printing out
List::Item* current = list.getFirstItemAddress();
while (current->next) {
std::cout << current->data << std::endl;
current = current->next;
}
return 0;
}
这是输出:
Testing output:
1168769696
-1064971727
Segmentation fault
但是,当我取消注释 testing-line 37 时,输出如下:
However, when I uncomment testing-line 37 this is the output:
Address: 0x7ffe54015cf0 -> 0
Address: 0x7ffe54015cf0 -> 1
Address: 0x7ffe54015cf0 -> 2
Address: 0x7ffe54015cf0 -> 3
Address: 0x7ffe54015cf0 -> 4
Testing output:
1648675776
1648572376
1646105840
1226279756
Segmentation fault
我一开始不明白输出如何如此剧烈地改变测试输出"的输出......
I don't understand in the first place how outputting can change the output of 'Testing output' this drastically...
无论如何,分段错误信息:
Anyway, segmentation fault info:
(gdb) run
Starting program: /home/niel/Desktop/listTest/main
Address: 0x7fffffffe0a0 -> 0
Address: 0x7fffffffe0a0 -> 1
Address: 0x7fffffffe0a0 -> 2
Address: 0x7fffffffe0a0 -> 3
Address: 0x7fffffffe0a0 -> 4
Testing output:
-136467520
-136570920
-139037456
1226279756
Program received signal SIGSEGV, Segmentation fault.
0x000000000040092e in main () at main.cpp:62
62 std::cout << current->data << std::endl;
不知道为什么 current->data 会出现分段错误,因为我给每个元素都提供了数据!
No idea why current->data gives the segmentation fault, as I gave data to each element!
但最困扰我的是:
Address: 0x7fffffffe0a0 -> 0
Address: 0x7fffffffe0a0 -> 1
Address: 0x7fffffffe0a0 -> 2
Address: 0x7fffffffe0a0 -> 3
Address: 0x7fffffffe0a0 -> 4
每个项目都有相同的地址,当然,这不是我的意思.在迭代中创建的每个项目都应该是具有另一个地址的另一个项目.这是否与 Item 被声明为本地有关,并且该对象因此存储在堆栈中而不是在可用空间中?我尝试使用 'new' 关键字,但没有奏效!
Each item has the same address, of course, this isn't what I meant. Each item created in the iterations should be another item with another address. Has this something to do with Item being declared local, and the object for that reason is stored on the stack and not in free space? I tried using the 'new' keyword, but that didn't work!
TL;DR1)为什么我得到分段错误2) 如何解决 List() 中创建的每个 Item 都有一个单独的地址?
TL;DR 1) Why am I getting the segmentation fault 2) How to fix that each Item created in List() has a separate address?
推荐答案
问题
在您的列表构造函数中,您将一个对象 item
的地址放入列表中,该对象是循环本地的,并在每次迭代结束时被销毁.
In your list constructor, you put in your list the address of an object item
that is local to the loop and gets destroyed at the end of each iteration.
解决方案
您必须在自由存储中创建一个 new
对象,这样它才能在迭代和构造函数结束时继续存在.在您学习的过程中,我保持简单并使用原始指针:
You have to create a new
object in the free store, so that it survives the iteration and the end of the constructor. As you're learning, i keep it simple and use raw pointers:
List(int size) {
for (int i = 0; i < size; i++) {
Item *pitem = new Item;
pitem->data = i;
if (i == 0)
start = pitem;
if (i > 0)
buffer->next = pitem;
//Storing current address in buffer
buffer = pitem;
//Outputting address and value (just for testing purposes)
//std::cout << "Address: " << pitem << " -> " << item->data << std::endl;
}
}
但是你的代码会泄漏内存.如果你有这样的构造函数,你还需要一个复制构造函数、一个赋值运算符和一个析构函数 (规则 3)
But then your code will leak memory. If you have such a constructor, you'll also need a copy constructor, an assignment operator and a destructor (rule of 3)
相关文章