呈现的代码中有几个错误,我将首先讨论这些错误,然后是我的指针与数组的股票描述。
struct charMap
{
unsigned int * name;
unsigned int id;
};
typedef struct charMap CharMapT;
这声明了一个结构类型,其中包括指向 unsigned int 作为第一个成员(名称)和一个 int 作为第二个成员(id)的指针。在具有默认字节打包的 32 位系统上,这将是8 字节宽(32 位指针 = 4 字节,32 位有符号整数 = 4 字节)。如果这是一台 64 位机器,指针将是 8 字节宽,int 仍然可能是 32 位宽,使结构大小为12 字节。
有问题的代码
void ABC::Function ()
{
CharMapT list[] =
{
{"NAME1", 1},
{"NAME2", 2},
{"NAME3", 3}
};
structList = new CharMapT[sizeof(list)];
memcpy(structList, &list, sizeof(list));
}
这会分配 CharMapT 结构的动态数组。多少?比你想象的更多。将返回数组sizeof(list)
的字节数。list[]
由于 CharMapT 结构为 8 字节宽(见上文),这将是 3 * 8 或24 个 CharMapT 项(如果使用 64 位指针,则为 36 项)。
然后我们将memcpy()
24字节(或 36 字节)从list
(&
in&list
是不必要的)到新分配的内存。这将复制超过 3 个 CharMapT 结构,而我们分配的其他 21 个结构保持不变(超出它们的初始默认构造)。
注意:您正在将 a 初始化为const char *
声明为 的字段unsigned int *
,因此即使编译了基本数据类型也会有所不同。假设您修复了结构并将指针类型更改为const char *
,则 const 数据段中某处的静态字符串常量的地址(“NAME”常量的地址)将分配给 structList[0] 中元素的指针变量.name、structList[2].name 和 structList[3].name 分别。
这不会复制指向的数据。它只会复制指针值。如果您想要数据的副本,那么您必须对它们进行原始分配(malloc、new 等)。
更好的是,使用 an std::vector<CharMapT>
、 use std::string
forCharMapT::name
和 usestd::copy()
来复制源代码(甚至直接赋值)。
我希望这能解释你在寻找什么。
指针与数组辱骂
永远不要将指针与数组混淆。指针是一个保存地址的变量。就像变量保存整数值,或者变量保存字符类型一样,指针中保存的值是地址int
char
数组是不同的。它也是一个变量(显然),但它不能是左值,并且几乎每个通常使用它的地方都会发生转换。从概念上讲,转换会产生一个临时指针,该指针指向数组的数据类型,并保存第一个元素的地址。有时该概念不会发生(例如应用地址运算符)。
void foo(const char * p)
{
}
char ar[] = "Hello, World!";
foo(ar); // passes 'ar', converted to `char*`, into foo.
// the parameter p in foo will *hold* this address
或这个:
char ar[] = "Goodbye, World!";
const char *p = ar; // ok. p now holds the address of first element in ar
++p; // ok. address in `p` changed to address (ar+1)
但不是这个:
char ar[] = "Goodbye, World!";
++ar; // error. nothing to increment.