【问题标题】:Pointer inside a node pointer节点指针内的指针
【发布时间】:2014-02-18 19:59:39
【问题描述】:

如果我创建如下节点

struct node
{
    char *ptr = (char *)malloc(sizeof(char));
}*current;
void main()
{
    node *temp = new node();
    current = temp;
}

上面的代码会自动将current->ptr 设置为temp->ptr 指向的位置吗?

【问题讨论】:

  • 这是完全无效的 C++ 代码。请通过具有严格警告和错误检查的编译器运行它,并使用更正的代码更新您的问题。
  • 你的代码不会做这些事情,因为它不会编译。
  • 抱歉,弄错了。立即编辑!

标签: c++ pointers data-structures malloc nodes


【解决方案1】:
struct node
{
    char *ptr = (char *)malloc(sizeof(char)); // INVALID
} *current;

首先,您不应该混合使用内存模型。如果您使用new,请坚持使用new。不要在newmalloc 之间跳动。

其次,这不是有效的 C++。你不能在声明中声明一个类成员并调用一个函数来初始化它(除非你正在使用 C++11 的新特性)。更新它以清理它看起来像:

struct node
{
    char* ptr; // declare the pointer
    node() : ptr(new char) { } // initialize the pointer in the constructor
    // NOTE:  should also add a copy constructor and copy-assignment operator here
    ~node()
    {
        delete ptr; // free the memory in the destructor
    }
};

int main() // NOTE that main must return an int, not void
{
    node current = new node();
    node temp = *current; // will do a shallow copy
    // ...
    delete current;
    // PROBLEM - temp now has a dangling pointer!
    return 0;
}

还要注意,在这种情况下,ptr 没有理由必须是指针。由于您只是动态分配单个char,因此您可以使用自动:

struct node
{
    char data;
    node() : data('\0') { }
};

int main()
{
    node current;
    node temp = current; // temp now has a copy of data, no problems
    return 0;
}

上面的代码会自动设置 current->ptr 指向哪里 temp->ptr 指向

您拥有的代码甚至无法编译,但如果您进行了修复,默认的复制赋值运算符将执行浅拷贝。在使用指针的情况下,这意味着您有 2 个对象都指向同一个内存位置。由于他们都认为自己拥有它,因此当其中一个破坏它时,另一个会留下一个悬空指针。

【讨论】:

  • 在我的实际代码中我必须分配max*sizeof(char)内存,所以我必须使用malloc。
  • @SrujanBarai sizeof(char) 保证始终为 1。没有理由使用 malloc 代替 new(除非与设计非常糟糕的遗留库接口),也没有理由在现代 C++ 中使用 new,甚至。
  • @SrujanBarai char* data = new char[max] - 除非这是为了家庭作业,教授告诉你使用malloc(出于某种奇怪的原因),否则你不必使用malloc 来执行此操作。
  • @SrujanBarai 您不需要使用 malloc。只需使用最大大小的字符数组。
  • 另外,char *ptr = (char *)malloc(sizeof(char)); 可能是正统的,但不是无效的。它在我的代码中运行良好!
【解决方案2】:

current 和 temp 指向内存中的同一位置。所以实际上 current->ptr is temp->ptr.

【讨论】:

  • 实际上当我执行我的代码时,当我更改current 的引用时,current->ptr 并没有改变它的引用。
【解决方案3】:

在使用赋值运算符的语句之后

current = temp;

current 和 temp 将具有相同的值。该值是节点类型对象的地址,它被分配到该地址。所以两个指针都指向对象占用的同一块内存。对象本身没有被复制或移动。

运算符 new 返回分配对象而不是对象本身的内存地址。所以在这句话之后

node *temp = new node();

变量 temp 将具有此地址及之后

current = temp;

current 和 temp 都会存储这个地址。

【讨论】:

  • 我的代码发生了什么,当我执行 current=temp 并向 *current->ptr 添加值时,current->ptr 仍然引用旧节​​点而不是引用 temp。这让我很困惑。
  • 两个变量都指向同一个节点。所以 *current->ptr = 'A';相当于 *temp->ptr = 'A'; temp 和 current 具有相同的值,
【解决方案4】:

是的,current->ptrtemp->ptr 指的是同一个内存地址。当您通过node* temp = new node() 实例化节点对象时,您的临时指针指向新分配的存储。通过current = temp 分配current 指针只会使当前指向该内存位置。请注意,current 指向的对象仍然存在于内存中的其他位置(以及 MAX 大小的字符数组),因为我们尚未释放该内存。此外,指针分配不会复制对象 - 它只是使指针指向不同的内存位置。引用currenttemp 指向的对象的任何成员,实际上将返回相同的值——无论它们是指针还是其他类型。

您的代码当前无效,无法编译。这是您打算做的固定版本。

#include<cstdlib>
#include<cstdio>

#define MAX 10

struct node
{
        char* ptr;
        node()
        {
           ptr = new char[MAX];  // Do not use malloc if using new elsewhere. 
        }

}*current;

int main()
{
    struct node* temp = new struct node();
    current = temp;

    // The pointer addresses will be the same. 
    printf("Current->ptr=%p, temp->ptr=%p\n", (void*)current->ptr,  (void*)temp->ptr);
    return 0;
}

【讨论】:

  • 最佳答案精度。 (y)
猜你喜欢
  • 2021-02-19
  • 1970-01-01
  • 2019-04-19
  • 2015-07-18
  • 1970-01-01
  • 2014-02-13
  • 1970-01-01
  • 2016-03-27
  • 1970-01-01
相关资源
最近更新 更多