简体   繁体   English

Malloc一个1维指针数组错误

[英]Malloc a 1 d array of pointers error

I am trying to malloc a 1 d array of pointers following a 1d array of struct type entry. 我正在尝试在结构类型条目的1d数组之后分配m的1d指针数组。

While making each pointer points to the correspondent element of the 1d array, I hit the problem. 在使每个指针指向1d数组的对应元素时,我遇到了问题。

The pointers stores at the beginning of the memory and each pointer points to the address of each entry. 指针存储在存储器的开头,每个指针指向每个条目的地址。

Below is a simple illustration: 下面是一个简单的例子:

--------------------------
ptr1|ptr2|ptr3|ptr4|ptr5
--------------------------
entry1
--------------------------
entry2
--------------------------
entry3
--------------------------
entry4
--------------------------
entry5
--------------------------


each pointer in the array of pointers points to entry 1- 5 accordingly.

Here is the code, 这是代码,

#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;
}

output: 输出:

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
                      ....

The program crashes when i = 16369. It seems to be memory access violation. 当i = 16369时,程序崩溃。这似乎是内存访问冲突。

My CPU is 64 bit, so the pointer size is 8 bytes. 我的CPU是64位,所以指针大小是8个字节。

However, while I am expecting the size of entry is 32byte, you can see the increment of phead[i] is 256. Can anyone explain that? 但是,虽然我期望条目的大小为32byte,但您可以看到phead [i]的增量为256。有人可以解释吗?

Thanks! 谢谢!

I am expecting the size of entry is 32byte, you can see the increment of phead[i] is 256. 我期望条目的大小为32byte,可以看到phead [i]的增量为256。
Can anyone explain that? 谁能解释一下?

Unexpected bad pointer math. 意外的错误指针数学。

//                                 + this adds by the size of *pHead 
// pHead[i] = (pHead + TABLE_SIZE) + (sizeof(entry) * i);

With compiler warnings fully enabled, OP may have received the below, hinting at the problem. 完全启用编译器警告后,OP可能会收到以下内容,提示问题。

warning: assignment from incompatible pointer type [-Wincompatible-pointer-types] 

Tip: Save time, enable all compiler warnings. 提示:节省时间,启用所有编译器警告。


There is also an alignment/size problem in that the 2nd half entry[] array may not align as needed. 还有一个对齐/大小问题,因为第二个half entry[]数组可能无法根据需要对齐。 @Ian Abbott 伊恩·雅培

A simple approach to avoid issues is to create a struct of the desired memory and allocate to that. 一种避免问题的简单方法是创建所需内存的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.
}

Output 产量

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
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM