簡體   English   中英

C - 如何為每個數組元素動態分配內存?

[英]C - How to dynamically allocate memory for each array element?

我有以下結構

typedef struct h{
        int key;
        float data;
        char name[20];
}heaparr;

我想為每個元素動態分配內存

heaparr *heap;

為了動態地為每個元素分配內存,我已經使用過

heap[i]=(heaparr*)malloc(sizeof(heaparr));

但每次編譯代碼時,都會出現賦值類型不匹配錯誤。 我該如何解決這個問題? 提前致謝。

您只能通過指針動態分配。 如果要動態分配數組的每個元素,則每個元素必須是指針。

[編輯]感謝@David C. Rankin 指出我在這個特定的例子中我在堆棧中聲明了一個包含10個指針的數組,以使代碼更簡單。 您可以使用任意數量的元素創建預定義大小的數組,但它具有一個限制,即一旦達到限制就無法重新realloc堆數據。 您始終可以動態創建數組。

#include <stdlib.h>

typedef struct h {
    int key;
    float data;
    char name[20];
} heaparr;

int main()
{
    heaparr *heap[10];
    int i;
    for (i = 0; i < 10; ++i) {
        heap[0] = malloc(sizeof(heaparr));
    }

    return 0;
}

作為TheCrow答案的后續內容,如果您確實希望以允許處理和未知數量的結構的方式為每個heap[i]分配,那么您可以使用指向 heaparr 的指針 (例如, heaparr **heap; )然后最初分配一些指針並為每個結構分配,因為它是從輸入中讀取的。

該計划是直截了當的。 你保留兩個計數器變量。 一個表示分配的指針數,第二個表示使用的數字。 當使用指針的數目等於分配數量,您只需realloc試圖分配/填充你的下一個指針之前,更多的指針。

以下是從stdin讀取數據並希望每行包含"key data name"的簡單示例。 最初分配了2指針,並且根據需要通過將當前分配的所有指針都已填充時分配的當前數量加倍來重新分配指針數,例如

#include <stdio.h>
#include <stdlib.h>

/* if you need constants, #define them or use a global enum */
enum { NPTR = 2, MAXNM = 20, MAXC = 128 };

typedef struct {
    int key;
    float data;
    char name[MAXNM];
} heaparr;

int main (void) {

    char buf[MAXC] = "";    /* read buffer */
    size_t  n = 0,          /* current struct filled */
            nptr = NPTR;    /* initial/current number of pointers */
    heaparr **heap = NULL;  /* pointer-to-pointer to heaparr */

    /* allocate/validate nptr to heap */
    if (!(heap = malloc (nptr * sizeof *heap))) {
        perror ("malloc-heap");
        return 1;
    }

    while (fgets (buf, MAXC, stdin)) {          /* read each line */
        heaparr tmp = { .key = 0 };             /* tmp struct */
        if (sscanf (buf, "%d %f %19[^'\n']",    /* parse line/validate */
                    &tmp.key, &tmp.data, tmp.name) != 3) {
            fprintf (stderr, "error: failed conversion line %zu.\n", n);
            continue;       /* just read next line on conversion failure */
        }
        if (n == nptr) {    /* check if realloc needed */
            /* always relloc to a temporary pointer to avoid mem-leak */
            void *tmpheap = realloc (heap, nptr * 2 * sizeof *heap);
            if (!tmpheap) { /* validate realloc */
                perror ("realloc-tmpheap");
                break;  /* don't exit, original data still valid in heap */
            }
            heap = tmpheap; /* assign new block to heap */
            nptr *= 2;      /* update current pointers allocated */
        }
        if (!(heap[n] = malloc (sizeof *heap[n]))) { /* allocate heap[n] */
            perror ("malloc-heap[n]");
            break;
        }
        *heap[n++] = tmp;   /* assign tmp to heap[n], increment n */
    }

    for (size_t i = 0; i < n; i++) {    /* output all values */
        printf ("%3d %5.1f   %s\n", heap[i]->key, heap[i]->data, 
                                    heap[i]->name);
        free (heap[i]);     /* don't forget to free each struct */
    }
    free (heap);            /* don't forget to free pointers */

    return 0;
}

(4個結構的數據如下所示,需要上面的realloc

示例輸入文件

$ cat dat/intfloatstr.txt
1 1.1 my
2 2.2 dog
3 3.3 has
4 4.4 fleas

示例使用/輸出

$ ./bin/dynallocstruct <dat/intfloatstr.txt
  1   1.1   my
  2   2.2   dog
  3   3.3   has
  4   4.4   fleas

內存使用/錯誤檢查

在您編寫的任何動態分配內存的代碼中,您對分配的任何內存塊都有2個職責 :(1) 始終保留指向內存塊起始地址的指針,因此,(2)當它為no時可以釋放它需要更久。

您必須使用內存錯誤檢查程序,以確保您不會嘗試訪問內存或寫入超出/超出已分配塊的范圍,嘗試讀取或基於未初始化值的條件跳轉,最后,確認你釋放了你分配的所有內存。

對於Linux, valgrind是正常的選擇。 每個平台都有類似的記憶檢查器。 它們都很簡單易用,只需通過它運行程序即可。

$ valgrind ./bin/dynallocstruct <dat/intfloatstr.txt
==8846== Memcheck, a memory error detector
==8846== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8846== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==8846== Command: ./bin/dynallocstruct
==8846==
  1   1.1   my
  2   2.2   dog
  3   3.3   has
  4   4.4   fleas
==8846==
==8846== HEAP SUMMARY:
==8846==     in use at exit: 0 bytes in 0 blocks
==8846==   total heap usage: 6 allocs, 6 frees, 160 bytes allocated
==8846==
==8846== All heap blocks were freed -- no leaks are possible
==8846==
==8846== For counts of detected and suppressed errors, rerun with: -v
==8846== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始終確認已釋放已分配的所有內存並且沒有內存錯誤。

您可以在指針的幫助下通過獲取下標的大小為每個數組索引分配內存,並啟動一個所需數組索引大小的循環。

也不需要對malloc的返回進行類型轉換。 找到如下所述的代碼段:

typedef struct h
{    
 int key;
 float data;
 char name[20];
}heaparr;

int main()
{
  int     size = 4;
  int     iLoop = 0;
  heaparr *heap[size];

  for (iLoop = 0; iLoop < size; iLoop++)
  {
    heap[iLoop] = malloc(sizeof(heaparr));
  } 
return 0;
}

希望這會清除你的懷疑。

我認為下面的代碼是適合你的...

int main
{
    ///In Main Function you need to allocate the memory for structure format  
     heaparr *heap;
     int num,i; //How many structures you want it?
     printf("Enter the size");
     scanf("%d",&num);
     heap=malloc(num*sizeof(struct heaparr));
     for(i=0;i<num;i++)
       scanf("%d %f %s",&heap[i].key,&heap[i].data,heap[i].name);//access members and store data
    for(i=0;i<num;i++)
       printf("%d %f %s",heap[i].key,heap[i].data,heap[i].name);//print the data

return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM