我正在尝试按照1d结构类型条目的数组对1 d指针数组进行malloc。
在使每个指针指向1d数组的对应元素时,我遇到了问题。
指针存储在内存的开头,每个指针指向每个条目的地址。
下面是一个简单的说明:
--------------------------
ptr1|ptr2|ptr3|ptr4|ptr5
--------------------------
entry1
--------------------------
entry2
--------------------------
entry3
--------------------------
entry4
--------------------------
entry5
--------------------------
each pointer in the array of pointers points to entry 1- 5 accordingly.
这是代码,
#include <stdio.h>
#define MAX_LAST_NAME_SIZE 16
#define TABLE_SIZE 131072 //2^17
typedef struct __PHONE_BOOK_DETAIL { //not really matter in this question
char firstName[16];
char city[16];
char zip[5];
} __PHONE_BOOK_DETAIL;
typedef struct __PHONE_BOOK_ENTRY { // the size is 16 + 8 +8 =32byte
char lastName[MAX_LAST_NAME_SIZE];
__PHONE_BOOK_DETAIL *detail;
struct __PHONE_BOOK_ENTRY *pNext;
} entry;
int main()
{
int i;
entry **pHead;
entry *e;
pHead = (entry **) malloc(sizeof(entry *)*TABLE_SIZE + sizeof(entry)* TABLE_SIZE);
for(i=0;i<TABLE_SIZE;i++){
pHead[i]= (pHead+ TABLE_SIZE) + sizeof(entry)*i;
printf("i=%d , phead[i]=%p &phead[i]=%p, sizeof (entry)=%d sizeof(e)=%d \n",i, pHead[i],&pHead[i],sizeof(entry),sizeof(e));
//pHead[i]->pNext=NULL;
}
return 0;
}
输出:
i=0 , phead[i]=6b597010 &phead[i]=6b497010, sizeof (entry)=32 sizeof(e)=8
i=1 , phead[i]=6b597110 &phead[i]=6b497018, sizeof (entry)=32 sizeof(e)=8
i=2 , phead[i]=6b597210 &phead[i]=6b497020, sizeof (entry)=32 sizeof(e)=8
i=3 , phead[i]=6b597310 &phead[i]=6b497028, sizeof (entry)=32 sizeof(e)=8
i=4 , phead[i]=6b597410 &phead[i]=6b497030, sizeof (entry)=32 sizeof(e)=8
i=5 , phead[i]=6b597510 &phead[i]=6b497038, sizeof (entry)=32 sizeof(e)=8
i=6 , phead[i]=6b597610 &phead[i]=6b497040, sizeof (entry)=32 sizeof(e)=8
i=7 , phead[i]=6b597710 &phead[i]=6b497048, sizeof (entry)=32 sizeof(e)=8
i=8 , phead[i]=6b597810 &phead[i]=6b497050, sizeof (entry)=32 sizeof(e)=8
i=9 , phead[i]=6b597910 &phead[i]=6b497058, sizeof (entry)=32 sizeof(e)=8
....
当i = 16369时程序崩溃。这似乎是内存访问违规。
我的CPU是64位,因此指针大小为8个字节。
然而,虽然我期望条目的大小是32byte,你可以看到phead [i]的增量是256.任何人都可以解释一下吗?
谢谢!
答案 0 :(得分:2)
我期望输入的大小是32byte,你可以看到phead [i]的增量是256.
任何人都可以解释一下吗?
意外的错误指针数学。
// + this adds by the size of *pHead
// pHead[i] = (pHead + TABLE_SIZE) + (sizeof(entry) * i);
在完全启用编译器警告的情况下,OP可能已收到以下信息,暗示了问题。
warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
提示:节省时间,启用所有编译器警告。
还存在对齐/大小问题,因为后半部分entry[]
数组可能无法根据需要对齐。 @Ian Abbott
避免问题的一个简单方法是创建所需内存的struct
并分配给它。
int main(void) {
// This is the memory layout that OP seeks
typedef struct {
entry *pHead[TABLE_SIZE];
// Compiler will determine if padding needed between the 2 members.
// OP's code reasonably assumed zero padding - yet best not to assume it.
entry e[TABLE_SIZE];
} all;
all *a = malloc(sizeof *a); // Simple!
if (a == NULL) {
return (EXIT_FAILURE);
}
entry **pHead = a->pHead;
entry *e = a->e;
for (size_t i = 0; i < TABLE_SIZE; i++) {
pHead[i] = &e[i];
printf( // format corrected
"i=%zu, phead[i]=%p &phead[i]=%p, sizeof (entry)=%zu sizeof(e)=%zu \n",
i, (void *) pHead[i], (void *) &pHead[i], sizeof entry, sizeof e);
}
free(pHead); // Note pHead and `a` point to the same memory.
}
输出
i=0, phead[i]=0x600061fc8 &phead[i]=0x600061f90, sizeof (entry)=32 sizeof(e)=8
i=1, phead[i]=0x600061fe8 &phead[i]=0x600061f98, sizeof (entry)=32 sizeof(e)=8
i=2, phead[i]=0x600062008 &phead[i]=0x600061fa0, sizeof (entry)=32 sizeof(e)=8
...