如何正确设置指向新结构的指针

How do I appropriately set the pointer to a new structure?

本文关键字:结构 指针 新结构 何正确 设置      更新时间:2023-10-16

我有一个关于在 c++ 中初始化新结构的问题。 我是 c++ 的新手。

typedef struct 
{
   int n;
   char anArray*;
}  myStruct;
void newStruct ( myStruct **ms, int x)
{
   myStruct* local_ms = new myStruct;
   local_ms->n = x;
   local_ms->anArray= new char[sizeof(char)*n];
   ms = &local_ms;
}

当我使用 void 指针调用 newStruct 时,我的目的是让它在 myStruct 中分配内存,然后将指向新结构的指针存储在 ms 中,供我以后使用。 不幸的是,我认为local_ms范围只是本地的,因此从newStruct返回时会丢失。

话虽如此,我不确定如何正确初始化 myStruct! 思潮?

"我认为local_ms范围只是局部的,因此在返回时会丢失 来自新结构。

改变:

ms = &local_ms;

自:

*ms = local_ms;

将有助于避免将newStruct对象的指针分配给*ms的问题。

ms = &local_ms;

这会修改本地指针ms,使其指向指向已分配结构的其他本地指针。但是,您想要的是修改调用方的指针。 ms是指向它的指针,因此您希望修改ms指向的内容:

*ms = local_ms;

但这不是 C,所以你可以使用更简单的引用语义:

void newStruct ( myStruct *& ms, int x)
//                        ^^ reference to pointer
{
    // ...
    ms = local_ms;
}
// usage
myStruct * ms;
newStruct(ms, 42);

但是语言(C 或 C++)提供了一种更简洁的方式来从函数返回值:您可以从函数返回值。

myStruct * newStruct(int x)
{
    // ...
    return local_ms;
}
// usage
myStruct * ms = newStruct(42);

但是在C++中,我们可以使用构造函数而不是任意函数来初始化新对象:

struct myStruct {              // no need for that typedef nonsense
    explicit myStruct(int n) : 
        n(n), 
        anArray(new char[n])   // sizeof(char) is 1 by definition
    {}
    int n;
    char *anArray;             // * goes before the variable name
};
// usage
myStruct ms(42);               // don't use `new` unless you really need it

现在只缺少一件事:anArray永远不会被删除,从而导致内存泄漏。最简单的解决方法是使用标准库中的动态数组类型:stringvector

struct myStruct {
    explicit myStruct(int n) : n(n), anArray(n) {}
    int n;
    std::string anArray;
};

但是,当然,n现在是多余的;你应该摆脱它,改用anArray.size()。这意味着结构本身毫无意义;你只需要

std::string ms(42);
#include <memory>
#include <iostream>
// [A] Starting with:
typedef struct
{
   int n;
   // Not char anArray*;
   char* anArray;
}  myStruct;
void newStruct ( myStruct **ms, int x)
{
   myStruct* local_ms = new myStruct;
   local_ms->n = x;
   // Fix: use x
   local_ms->anArray = new char[sizeof(char)*x];
   ms = &local_ms;
}
//  [B] Avoid myStruct **ms, use std::size_t
//      and get rid of sizeof(char) (which is one, always)
myStruct* newStruct (std::size_t x)
{
   myStruct* ms = new myStruct;
   ms->n = x;
   ms->anArray= new char[x];
   return ms;
}
// [C] Manage memory in a class (pair new/delete).
//     Btw. typedef struct is C (not C++)
class myStruct2
{
    public:
    myStruct2(std::size_t n)
    :   n(n), anArray(new char[n])
    {}
    ~myStruct2() {
        delete [] anArray;
    }
    std::size_t size() const { return n; }
    const char* array() const { return anArray; }
    char* array() { return anArray; }

    private:
    // If you do not define these, avoid copies (C++11 has '= delete'):
    myStruct2(const myStruct2&);
    myStruct2& operator = (const myStruct2&);
    std::size_t n;
    char* anArray;
};
// Still having a new without delete in the same (logically) scope - which is bad:
myStruct2* newStruct2 (std::size_t n)
{
   return new myStruct2(n);
}
// [D] Manage memory with a shared pointer.
// Still having an new without a delete in the same (logically) scope,
// but now the memory is managed by the shared pointer - that is good!
// (If there is no std::shared_ptr: boost::shared_ptr)
std::shared_ptr<myStruct2> make_shared_struct2(std::size_t n)
{
   return std::shared_ptr<myStruct2>(new myStruct2(n));
}
// [E] Avoid the pointer to myStruct2
// If you have defined the copy constructor and assignment operator:
// myStruct2 make_struct2(std::size_t n)
// {
//    return myStruct2(n);
// }
// [F] But actually it is trivial
typedef std::vector<char> myStruct3;
myStruct3 make_struct3(std::size_t n)
{
    return myStruct3(n);
}