我一直试图在创建int
指针后更改其指向的地址。尽管起初是可行的,但是连续更改指针值的函数调用不会更改我打算更改的原始值,而只会在函数中局部影响值。我认为,由于递归函数调用之间的某种原因,指针可能会更改其值。
我正在尝试创建将生成电路网表的代码。它递归地遍历二叉树,在创建节点时将一对指针返回一个指针,该对分别代表该节点的开始和结束值。当从二叉树的2个子节点中的每个子节点获得一对时,我的代码然后合并2个节点,使指针指向2个节点之一的末端,等于另一个,以便它们都共享相同的值(通过poiting到相同的地址),如果稍后更改2个值之一,则2个值都会更改,因为它们现在都指向相同的位置。然后它返回指向第一个节点的起点和第二个节点的终点的指针。然后,该对将返回以用作其父级的子级。
奇怪的是,第一次2对被合并时,它会正确更改原始指针的值,但是当我多次调用它时并不会更改。
我将指针返回指针的原因是,我无法返回对该指针的引用,因此无法更改原始值,因此,要解决此问题,我将返回指向该指针的指针我想改变。
使用create_and
和create_or
函数时会出现问题。
std::pair<int**, int**> create_and(std::pair<int**, int**> &in1, std::pair<int**, int**> &in2) {
delete *in2.first;
*in2.first = *in1.second;
in2.first = in1.second;
return {in1.first, in2.second};
}
std::pair<int**, int**> create_or(std::pair<int**, int**> &in1, std::pair<int**, int**> &in2) {
delete *in2.first;
delete *in2.second;
*in2.first = *in1.first;
in2.first = in1.first;
*in2.second = *in1.second;
in2.second = in1.second;
return {in1.first, in1.second};
}
完整代码以及测试用例
#include <iostream>
#include <cstring>
#include <vector>
const int N = 1e3;
char tree[N] = {'&', '|', '|', 'a', 'b', 'c', 'd', 0, 0, 0, 0, 0, 0, 0, 0};
struct mos {
int* drn;
int* bdy;
int* snk;
};
std::vector<mos*> up_netlist, down_netlist;
int* Vdd, *gnd;
int uni1 = 105;
int nMOS = 0, pMOS = 0;
int inter = 1000;
int count = 0;
int inter1 = 1000;
bool up_down;
std::pair<int**, int**> get_ends(int = 0);
std::pair<int**, int**> create_and(std::pair<int**, int**>&, std::pair<int**, int**>&);
std::pair<int**, int**> create_or(std::pair<int**, int**>&, std::pair<int**, int**>&);
std::pair<int*, int*> create_not(std::pair<int*, int*>&);
int main(){
//memset(tree, -1, sizeof tree);
Vdd = new int;
*Vdd = 1;
gnd = new int;
*gnd = -1;
int* y = new int;
*y = 111;
up_down = true;
std::pair<int**, int**> up = get_ends(); //returns a pair of pointers that are the start and end wire for the generated pull up network
up_down = false;
std::pair<int**, int**> down = get_ends();
**up.first = *Vdd; //make start = Vdd
**up.second = *y; //make end = y
**down.first = *y;
**down.second = *gnd;
std::cout << "Vdd: " << **up.first << std::endl << "Gnd: " << **down.second << std::endl << std::endl << std::endl << "Netlist: " << std::endl << std::endl;
int j = 0;
for (auto i : up_netlist) {
std::cout << 'M' << j++ << ' ' << *i->snk << ' ' << *i->bdy << ' ' << *i->drn << ' ' << *i->drn << ' ' << "PMOS" << std::endl; //printing netlist
}
for (auto i : down_netlist) {
std::cout << 'M' << j++ << ' ' << *i->snk << ' ' << *i->bdy << ' ' << *i->drn << ' ' << *i->drn << ' ' << "NMOS" << std::endl;
}
return 0;
}
//To better interpret this, suppose the view from the function opinion is just a tree with a parent and 2 children nodes with each node presenting a circuit (except the parent). The children return the their start and end wires to the parent. The parent then combines the 4 wires together down to 2 according to the parent's value. The parent then returns the 2 new wires.
std::pair<int**, int**> get_ends(int parent_loc) {
char parent = tree[parent_loc]; //parent to evaluate
int child_1_loc = parent_loc * 2 + 1, child_2_loc = child_1_loc + 1; //location of parents children
char child_1 = tree[child_1_loc]; //value of child
char child_2 = tree[child_2_loc]; //value of child
std::pair<int**, int**> child_1_end, child_2_end; //will be the start and end wires that will be recursively returned
if (child_1 != 0) {
child_1_end = get_ends(child_1_loc); //start and end wires of child 1
}
if (child_2 != 0) {
child_2_end = get_ends(child_2_loc); //start and end wires of child 2
}
std::pair<int**, int**> ret;
if (child_1 != 0 && child_2 != 0) { //enter case if children not null and parent is one of &, | or '. meaning the children have their start and end wires ready
switch (parent) {
case '&' : if (up_down) {
ret = create_and(child_1_end, child_2_end);
} else {
ret = create_or(child_1_end, child_2_end);
}
break;
case '|': if (up_down) {
ret = create_or(child_1_end, child_2_end);
} else {
ret = create_and(child_1_end, child_2_end);
}
break;
case '\'': //ret = create_not(child_1_end);
break;
default: std::cout << "ERROR";
}
} else { //this creates the start and end wires that are to be combined
mos* new_mos = new mos;
new_mos->bdy = new int;
*new_mos->bdy = parent;
new_mos->drn = new int;
*new_mos->drn= ++uni1;
new_mos->snk = new int;
*new_mos->snk = ++uni1;
if (up_down) {
up_netlist.push_back(new_mos); //push to the netlist so we can output it later and values are still changed in the netlist due to pointers
} else {
down_netlist.push_back(new_mos);
}
ret = {&new_mos->drn, &new_mos->snk}; //start and end of a single MOSFET
}
return ret;
}
std::pair<int**, int**> create_and(std::pair<int**, int**> &in1, std::pair<int**, int**> &in2) {
delete *in2.first;
*in2.first = *in1.second;
in2.first = in1.second;
return {in1.first, in2.second};
}
std::pair<int**, int**> create_or(std::pair<int**, int**> &in1, std::pair<int**, int**> &in2) {
delete *in2.first;
delete *in2.second;
*in2.first = *in1.first;
in2.first = in1.first;
*in2.second = *in1.second;
in2.second = in1.second;
return {in1.first, in1.second};
}
std::pair<int*, int*> create_not(std::pair<int*, int*> &in) {
int* inter = new int;
*inter = inter1;
mos* new_mos = new mos;
new_mos->bdy = in.second;
new_mos->drn = Vdd;
new_mos->snk = inter;
mos* new_mos_2 = new mos;
new_mos_2->bdy = in.second;
new_mos_2->drn = inter;
new_mos_2->snk = gnd;
return {in.first, inter};
}
结果是:
M0 107 97 1 1 PMOS
M1 107 98 1 1 PMOS
M2 111 99 107 107 PMOS
M3 111 100 431886464 431886464 PMOS
M4 115 97 111 111 NMOS
M5 -1 98 115 115 NMOS
M6 119 99 111 111 NMOS
M7 -1 100 119 119 NMOS
我要更改的原始指针未正确更新。
应该在什么时候出现:
M0 107 97 1 1 PMOS
M1 107 98 1 1 PMOS
M2 111 99 107 107 PMOS
M3 111 100 107 107 PMOS
M4 115 97 111 111 NMOS
M5 -1 98 115 115 NMOS
M6 119 99 111 111 NMOS
M7 -1 100 119 119 NMOS
错误的值应指向存储107的相同地址。