我有一个关于在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!想法?
答案 0 :(得分:1)
“我认为local_ms只在本地范围内,因此在返回时会丢失 来自newStruct。“
变化:
ms = &local_ms;
为:
*ms = local_ms;
有助于避免问题,该问题会将newStruct
对象的指针指定给*ms
。
答案 1 :(得分:0)
ms = &local_ms;
这会修改 local 指针ms
以指向指向已分配结构的其他 local 指针。但是,您想要的是修改调用者的指针。 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
,导致内存泄漏。最简单的解决方法是使用标准库中的动态数组类型:string
或vector
。
struct myStruct {
explicit myStruct(int n) : n(n), anArray(n) {}
int n;
std::string anArray;
};
但当然,n
现在是多余的;你应该摆脱它并使用anArray.size()
代替。这意味着结构本身毫无意义;你只需要
std::string ms(42);
答案 2 :(得分:0)
#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);
}