是否有任何理由不会将堆指针分配给数组?
Posted
技术标签:
【中文标题】是否有任何理由不会将堆指针分配给数组?【英文标题】:Is there any reason that a heap pointer would not get assigned to an array? 【发布时间】:2019-11-03 14:03:01 【问题描述】:Node的结构如下:
struct Node
int data;
Node *next;
bool someBool;
;
我有以下几行:
Node *hello = new Nodedata, cur, !new_head; // line A
array[new_head_index] = hello; // line B
// line C
new_head_index
的值在所有 3 行上都被 GDB 确认为 1。
GDB 确认,在 A、B 和 C 行,当我执行 p *hello
(打印 hello
的内容)时,我得到:
(gdb) p *hello
$7 = data = 888, next = 0x8414e70, someBool = false
但是打印array@2
的内容(数组长度为2,在main 中声明为Node *heads[numHeads] = new Node0, nullptr, false, nullptr;
)在B 行和C 行有这个(在行实际执行之前):
(gdb) p **array@2
$8 = data = 777, next = 0x8414e70, someBool = true, data = 33, next = 0x378, someBool = 112
(应该是777节点,我之前填过)。
在 A 行,它有:
(gdb) p **array@2
$9 = data = 777, next = 0x8414e70, someBool = true, data = 61265, next = 0x0, someBool = false
基本上,hello
没有分配给array[1]
。这可能是什么原因?
这是一个最小的可重现示例: main.cc
#include <iostream>
#include <string>
#include "new_mod.h"
using namespace std;
int len(Node **array)
int i = 0, count = 0;
while (array[i++]) ++count;
return count;
void attach(Node **array, int head, int index, int data)
Node *hello = new Nodedata, cur;
array[new_head_index] = hello;
int main()
string command;
int head;
Node *array[numHeads] = new Node0, nullptr, nullptr;
while (cin >> command)
if (command == "a")
int m, x;
cin >> head >> m >> x;
attach(array, head, m, x);
mod.h
#ifndef MOD_H
#define MOD_H
#include <ostream>
struct Node
int data;
Node *next;
bool someBool = false;
;
const int numHeads = 2;
void attach(Node **array, int head, int index, int data);
#endif
尝试输入此输入(我已将此文件命名为 a.in
)
a 0 0 777
a 0 1 888
用g++ -Wall -g main.cc -o newe
编译,这样你就可以用gdb 做事了!
顺便说一下,这是我在 gdb 中为解决上述问题所做的:
gdb newe
b attach(Node**, int, int, int)
run <a.in
layout n
c
n
n
n
n
n
n
n (comment: I did n until line Node *hello = new Nodedata, cur;)
p **array@2
n
n
p **array@2 (the problem is shown)
【问题讨论】:
minimal reproducible example 会更容易查看。 @PaulMcKenzie 好的,给你 【参考方案1】:问题在于Node *array[2]
和Node **array
是不同一件事,当您向GDB 询问p **array@2
时,您要求将数组解释为好像array
是一个双指针,不是数组。
您可以在开始输入循环之前观察到这一点:
(gdb) p *array@2
$1 = 0x55555556ae70, 0x0
(gdb) p *array[0]
$2 = data = 0, next = 0x0, someBool = false
在这里,您可以看到 array
处于预期状态:第一个节点全为零,第二个节点为 NULL。
但是当你这样做时:
(gdb) p **array@2
$3 = data = 0, next = 0x0, someBool = false, data = 4113, next = 0x3737203020302061, someBool = 55
您可以立即看到您没有查看正确的数据:您知道 array[1]
是 NULL,所以它不能指向 @ 987654330@ 里面有4113
。
我不相信print *array[0 .. N]
有 GDB 内置语法。
一种可能的解决方案是定义一个辅助函数(它可以很容易地概括为将数组名称和大小作为参数,但为了简单起见,这里保持微不足道):
(gdb) def parray
Type commands for definition of "parray".
End with a line saying just "end".
>print *array[0]
>print *array[1]
>end
(gdb) parray
$4 = data = 0, next = 0x0, someBool = false
Cannot access memory at address 0x0
(gdb) c
Continuing.
Breakpoint 1, attach (array=0x7fffffffdb70, head=0, index=1, data=888) at foo.cc:34
34 array[new_head_index] = hello;
(gdb) n
35
(gdb) parray
$5 = data = 777, next = 0x55555556ae70, someBool = false
$6 = data = 888, next = 0x55555556ae70, someBool = false
【讨论】:
我什至不知道什么是双指针。但是当我一周前开始使用 gdb 时,我查找了如何执行“打印数组”,我发现了这个 SO 问题: ***.com/questions/14502236/…。而且我认为到目前为止,对于我过去尝试过的阵列来说,这一切都很好。那么这个答案错了吗? 答案没有错,print *array@2
工作正常。但是您不想打印数组元素的指针值;你想打印 dereferenced 指针,这是不同的。
另外,另一个问题是“如何将指针打印为数组”。这里你有一个数组,所以简单的p array
可以打印它的值。
有什么区别?当我搜索“数组元素的指针值”时,我什么也找不到。你只是说地址吗?我的意思是 array
在这种情况下是一个指针数组,这就是为什么你必须取消引用它两次,否则它会给你地址(我认为“指针值”你可能是指地址),但如果它只是一个指针像int
或struct
这样的东西,然后像p *array@2
这样的东西没有给我地址,它给了我实际的值.. 你如何解释这个?
" "另外,另一个问题是'如何将指针打印为数组'。这里有一个数组,很简单p array
可以打印它的值。" p array
在我的示例中仅打印 $13 = (Node **) 0x7ffffffee150
。这就是您所说的“数组”吗?这对我来说不是有用的信息。以上是关于是否有任何理由不会将堆指针分配给数组?的主要内容,如果未能解决你的问题,请参考以下文章
是否有任何理由为啥我的 UITableViewCell 的覆盖 setHighlighted 不会被调用但 UITableViewDelegate 方法会?
在C ++中,是否有任何理由产生并立即加入一个线程,而不是直接调用该函数?
是否有任何理由继续使用 IntentService 处理 GCM 消息?