注册 登录
编程论坛 C++教室

关于结构体二级指针用memset初始化的困扰

lllyyy3 发布于 2022-10-15 16:36, 1487 次点击
程序代码:

typedef struct Node1 {
    int pass;
    int end;
    Node1** array;
    Node1() {
        pass = 0;
        end = 0;
        array = new Node1 * [10];
        for (int i = 0; i < 10; i++){
            array[i] = new Node1[5];
            memset(array[i], 0, 5 * sizeof(Node1)); //注意这里是array[i]
        }
    }
};

上述代码是在一个结构体的构造函数内分配内存并且初始化。
但是代码会在array = new Node1 * [10];这里抛出异常:有未经处理的异常: 0xC00000FD: Stack overflow (参数: 0x00000001, 0x003B2FFC)。
但是把array改为别的类型,比如另一个结构体或基础类型的二级指针,按照上面那样分配内存并且初始化就不会有异常。
是因为结构体里不能有自己类型本身的二级指针吗?
困扰很久了,希望各位大佬能帮忙解答
8 回复
#2
rjsp2022-10-15 18:40
array[i] = new Node1[5];
你欲构造出一个 Node1,就需要先构造出 50 个Node1,而这50个Node1,又需要构造各种的50个Node1,……,子子孙孙无穷尽也。

memset(array[i], 0, 5 * sizeof(Node1));
你既实现自己的构造,又用menset抹平。先不谈在 非is_trivially_copyable 对象上调用memset属于未定义行为,就这行为逻辑而言,得趁早
#3
lllyyy32022-10-15 20:19
回复 2楼 rjsp
我的想法是创建一个Node1的结构体,里面里面有指向一个数组的指针,这个数组里存的都是Node1类型的指针,因此我就想那干脆直接直接写成Node1**,那这个想法是不能实现吗?
而构造函数里面用memset是因为想要用null初始化这个二级指针。
#4
rjsp2022-10-15 20:54
是这个意思吗?
程序代码:
struct Node
{
    int pass = 0;
    int end = 0;
    Node* array[10] = { nullptr };

    Node() noexcept = default;
};


你把具体要求贴出来,目标不明,讨论实现没意义
#5
lllyyy32022-10-16 00:23
以下是引用rjsp在2022-10-15 20:54:05的发言:

是这个意思吗?
struct Node
{
    int pass = 0;
    int end = 0;
    Node* array[10] = { nullptr };

    Node() noexcept = default;
};

你把具体要求贴出来,目标不明,讨论实现没意义


这个问题是做力扣‘前缀树’这道题的时候产生的,存下一个字符的时候需要数组里放指针这样的操作,题解确实是Node* array[10];这样写的。
所以是不是用Node** array这种形式就实现不了,只能用Node* array[10]这种形式?
之所以有这样的疑问,是因为我感觉弄个指针然后动态分配内存和直接弄数组效果一样么,所以就用了Node** array,没用Node* array[10];
#6
apull2022-10-16 08:13
for里的 array[i] = new Node1[5];时,每次new一个会调用一次Node1(),也就再一次for,再一次new,这样无穷的递归下去了。

[此贴子已经被作者于2022-10-16 08:14编辑过]

#7
lllyyy32022-10-16 08:42
以下是引用apull在2022-10-16 08:13:38的发言:

for里的 array = new Node1[5];时,每次new一个会调用一次Node1(),也就再一次for,再一次new,这样无穷的递归下去了。


array = new Node1[5];这句我原来理解的是只分配5个Node1类型大小的内存还没放东西,返回个指针,这期间没有对象产生,只是有了内存空间。
按照你的这个说法,意思是分配内存的同时,也会调用构造函数产生5个这样的对象,所以才陷入无限调用是吗?
#8
apull2022-10-16 08:59
new的时候调用默认构造的。
#9
lllyyy32022-10-16 09:18
以下是引用apull在2022-10-16 08:59:07的发言:

new的时候调用默认构造的。

谢谢哥,我明白了,new本来就是两步组成的,分配内存和创建对象。
是一直说new动态分配内存new动态分配内存,我就只记得分配内存了,把对象创建给忘了。
1