1

The structure of Node is the following:

struct Node {
    int data;
    Node *next;
    bool someBool;
};

I have the following couple of lines:

    Node *hello = new Node{data, cur, !new_head}; // line A
    array[new_head_index] = hello;                // line B
}                                                 // line C

Value of new_head_index is confirmed to be 1 by GDB on all 3 lines.

GDB confirms, on lines A, B, and C, when I do p *hello (print the contents of hello), I get:

(gdb) p *hello
$7 = {data = 888, next = 0x8414e70, someBool = false}

But printing the contents of array@2 (array has length 2, declared in main as Node *heads[numHeads] = {new Node{0, nullptr, false}, nullptr};) has this on lines B and C (before line is actually executed):

(gdb) p **array@2
$8 = {{data = 777, next = 0x8414e70, someBool = true}, {data = 33, next = 0x378, someBool = 112}}

(The 777 node is expected, I filled it in before).

While on line A, it has:

(gdb) p **array@2
$9 = {{data = 777, next = 0x8414e70, someBool = true}, {data = 61265, next = 0x0, someBool = false}}

Essentially, hello is not being assigned to array[1]. What could be a possible reason for this?

Here is a minimal reproducible example: 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 Node{data, cur};
    array[new_head_index] = hello;
}

int main() {
    string command;
    int head;
    Node *array[numHeads] = {new Node{0, 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

Try putting in this input (I've named this file a.in)

a 0 0 777
a 0 1 888

Compile with g++ -Wall -g main.cc -o newe so you can do things with gdb!

By the way, here's what I did in gdb to get the above problem:

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 Node{data, cur};)
p **array@2
n
n
p **array@2 (the problem is shown)
herophant
  • 642
  • 7
  • 16

1 Answers1

0

The problem is that Node *array[2] and Node **array are not the same thing, and when you ask GDB to p **array@2, you are asking to interpret array as if array was a double pointer, not an array.

You can observe this before starting the input loop:

(gdb) p *array@2
$1 = {0x55555556ae70, 0x0}
(gdb) p *array[0]
$2 = {data = 0, next = 0x0, someBool = false}

Here, you can see that array is in expected state: first node is all zeros, second is NULL.

But when you do:

(gdb) p **array@2
$3 = {{data = 0, next = 0x0, someBool = false}, {data = 4113, next = 0x3737203020302061, someBool = 55}}

you can immediately see that you are not looking at the right data: you know that array[1] is NULL, so it can't be pointing to a Node with 4113 in it.

I don't believe there is a GDB built-in syntax to print *array[0 .. N]. One possible solution is to define a helper function (which can easily be generalized to take the array name and size as parameters, but is kept trivial here for simplicity):

(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}
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • I don't even know what a double pointer is.. But when I started to use gdb a week ago, I looked up how to do "print an array", I found this SO question: https://stackoverflow.com/questions/14502236/how-to-view-a-pointer-like-an-array-in-gdb. And I thought this was working well up until now for the arrays I've tried in the past. Is this answer wrong then? – herophant Nov 03 '19 at 16:47
  • The answer is not wrong, and `print *array@2` is working correctly. But you don't want to print the pointer values of array elements; you want to print *dereferenced* pointers, and that is different. – Employed Russian Nov 03 '19 at 16:55
  • Also, the other question is "how to print pointer as an array". Here you *have* an array, so simple `p array` works to print its values. – Employed Russian Nov 03 '19 at 17:02
  • What is the difference? I can't find anything when I search for "pointer values of array elements". Do you just mean addresses? I mean `array` in this case is an array of pointers, that's why you have to dereference it twice, otherwise it will give you addresses (I think by "pointer value" you might mean address), but if it was just a pointer of something like an `int` or a `struct`, then something like `p *array@2` did not give me addresses, it gave me the actual values.. How do you explain this? – herophant Nov 03 '19 at 17:04
  • " "Also, the other question is 'how to print pointer as an array". Here you have an array, so simple `p array` works to print its values." `p array` only prints `$13 = (Node **) 0x7ffffffee150` in my example. Is this what you are referring to as the "array"? This isn't useful information for me. – herophant Nov 03 '19 at 17:05