所以我正在研究一个小的内存分配程序包,我希望初始化指针来节省分配空间的大小,以及指示它是通过我的一个函数分配的(这是内存大小前的字符“ q”)。因此,我尝试执行以下操作:
int qmem_alloc(unsigned num_bytes, void ** rslt){
*rslt = malloc(num_bytes+sizeof(int)+sizeof(char));
*((int*)rslt) = num_bytes;
*(char*)(rslt+sizeof(int)) = 'q';
rslt = rslt+sizeof(int) + sizeof(char);
if(*rslt == NULL)
return -1;
else if(errno != 0){
//Catch the rest of the errors
return -2;
}
return 0;
}
但是,在我的主要功能中,似乎rslt地址之前的内存不包含回传后应该包含的内容。我在这里通过更改指针地址做不好的事情吗?
答案 0 :(得分:1)
您在某些地方缺少某种程度的间接性。在取消引用之前,您使用rslt
的任何地方都应该使用*rslt
:
int qmem_alloc(unsigned num_bytes, void ** rslt){
*rslt = malloc(num_bytes+sizeof(int)+sizeof(char));
if(*rslt == NULL)
return -1;
*((int*)*rslt) = num_bytes;
*(char*)(*rslt+sizeof(int)) = 'q';
*rslt = *rslt+sizeof(int) + sizeof(char);
if(errno != 0){
//Catch the rest of the errors
return -2;
}
return 0;
}
此外,malloc
返回的内存可以正确对齐以用于任何用途。因为您返回的sizeof(int)+sizeof(char)
==超出了5个字节(假设有4个字节的int
),这意味着您返回的指针可能不是。您需要再增加至少3个字节,以将返回的缓冲区置于8个字节的边界上。
答案 1 :(得分:0)
函数内部 rslt 是指针的地址。您不应该修改甚至访问它。如果您尝试更改/读取指针所指向的地址,则需要使用 * rslt 。如果尝试修改/读取指针所指向的值,则需要使用 ** rslt 。
@dbush在代码中描述了上面的结果。