前几天我正在考虑这个问题,如果这是一个坏主意我很好奇...让我们说有一个结构包含一个指向字符串数组的指针.memcpy()会复制下面示例中的'name'数组指针吗?编辑:此示例中无法访问std.
struct charMap
{
unsigned char * name;
unsigned char id;
};
typedef struct charMap CharMapT;
class ABC
{
public:
ABC(){}
void Function();
CharMapT* structList;
}
void ABC::Function ()
{
CharMapT list[] =
{
{"NAME1", 1},
{"NAME2", 2},
{"NAME3", 3}
};
structList = new CharMapT[sizeof(list)];
memcpy(structList, &list, sizeof(list));
}
Run Code Online (Sandbox Code Playgroud)
在我们将要讨论的代码中有几个错误,我将首先讨论这个错误,然后是指针与数组的指针.
struct charMap
{
unsigned int * name;
unsigned int id;
};
typedef struct charMap CharMapT;
Run Code Online (Sandbox Code Playgroud)
这声明了一种结构类型,其中包含指向unsigned int的指针作为第一个成员(name),int作为第二个成员(id).在具有默认字节打包的32位系统上,这将是8字节宽(32位指针= 4字节,32位符号int = 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));
}
Run Code Online (Sandbox Code Playgroud)
这将分配CharMapT结构的动态数组.多少?比你想象的更多.在sizeof(list)将返回的字节数list[]阵列.由于CharMapT结构宽度为8个字节(见上文),因此这将是3*8或24个CharMapT项目(如果使用64位指针则为36项).
然后,我们memcpy()24 个字节从(或36个字节)list(在&中&list是不必要的)到新分配的内存.这将复制3个CharMapT结构,留下我们分配的其他21个(超出其初始默认构造).
注意:你正在初始化一个const char *声明为的字段unsigned int *,所以如果这甚至编译了基本数据类型会有所不同.假设您修改了结构并将指针类型更改为const char *,则const数据段中某处的静态字符串常量地址("NAME"常量的地址)将分配给structList [0]中元素的指针变量.name,structList [2] .name和structList [3] .name分别.
这将不复制数据指出来.它只会复制指针值.如果你想要数据的副本,那么你必须对它们进行原始分配(malloc,new,等等).
更妙的是,使用std::vector<CharMapT>,使用std::string的CharMapT::name,并使用std::copy()复制源(甚至直接分配).
我希望能解释你在寻找什么.
Pointer与Array Diatribe
切勿将指针与数组混淆.指针是一个可变的是保持一个地址.就像int变量保存整数值或char变量保存字符类型一样,指针中保存的值是地址
数组是不同的.它也是一个变量(显然),但它不能是l值,几乎每个地方通常都会使用转换.从概念上讲,转换会产生一个指向数组数据类型的临时指针,并保存第一个元素的地址.有些时候,这种概念并没有发生(如应用地址运算符).
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
Run Code Online (Sandbox Code Playgroud)
或这个:
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)
Run Code Online (Sandbox Code Playgroud)
但不是这个:
char ar[] = "Goodbye, World!";
++ar; // error. nothing to increment.
Run Code Online (Sandbox Code Playgroud)