【发布时间】:2018-06-30 05:08:58
【问题描述】:
我正在尝试创建一个自己的列表类,它具有固定大小并且可以存储整数。仅用于学习目的。
这就是我的做法: 我有一个名为 Item 的结构,它保存数据(要存储的整数)和指向列表中下一项的指针。 当列表初始化时,我首先将 x 数量的空项添加到列表中。
迭代(n-1)中声明的item的地址存储在缓冲区中,这样迭代n中的item的地址,可以设置为上一次迭代(n-1)中的item的下一个。 这将所有项目相互链接。
第一个项目的地址也被保存下来,作为后面代码中整个列表的访问点。
但这并没有真正起作用;这是我的代码:
#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 时,输出如下:
Address: 0x7ffe54015cf0 -> 0
Address: 0x7ffe54015cf0 -> 1
Address: 0x7ffe54015cf0 -> 2
Address: 0x7ffe54015cf0 -> 3
Address: 0x7ffe54015cf0 -> 4
Testing output:
1648675776
1648572376
1646105840
1226279756
Segmentation fault
我一开始不明白输出如何如此剧烈地改变“测试输出”的输出......
无论如何,分段错误信息:
(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 会出现分段错误,因为我给每个元素都提供了数据!
但最困扰我的是:
Address: 0x7fffffffe0a0 -> 0
Address: 0x7fffffffe0a0 -> 1
Address: 0x7fffffffe0a0 -> 2
Address: 0x7fffffffe0a0 -> 3
Address: 0x7fffffffe0a0 -> 4
每个项目都有相同的地址,当然,这不是我的意思。在迭代中创建的每个项目都应该是具有另一个地址的另一个项目。 这是否与 Item 被声明为本地有关,并且该对象因此存储在堆栈中而不是在可用空间中?我尝试使用 'new' 关键字,但没有奏效!
TL;DR 1)为什么我得到分段错误 2) 如何解决 List() 中创建的每个 Item 都有一个单独的地址?
【问题讨论】:
-
使用
new为Item分配内存。为什么你会期望一个本地存储分配变量在循环的每次迭代中都有不同的地址? -
存储
&item以供以后使用是没有意义的,因为item的生命周期以创建它的迭代结束。之后取消引用它是未定义的。
标签: c++ pointers memory segmentation-fault