[英]Reallocating memory for a struct array in C
我在使用結構數組時遇到麻煩。 我需要逐行讀取文本文件,並比較各個值。 例如,“媽媽”會在上午1點返回2 ma,因為您有媽媽。 我有一個結構:
typedef struct{
char first, second;
int count;
} pair;
我需要為整個字符串創建一個結構數組,然后比較這些結構。 還介紹了內存分配,因此我們必須對任何大小的文件進行分配。 那才是我真正的麻煩所在。如何為結構數組正確地重新分配內存? 到目前為止,這是我的主要技能(不編譯,顯然有錯誤,此操作很麻煩)。
int main(int argc, char *argv[]){
//allocate memory for struct
pair *p = (pair*) malloc(sizeof(pair));
//if memory allocated
if(p != NULL){
//Attempt to open io files
for(int i = 1; i<= argc; i++){
FILE * fileIn = fopen(argv[i],"r");
if(fileIn != NULL){
//Read in file to string
char lineString[137];
while(fgets(lineString,137,fileIn) != NULL){
//Need to reallocate here, sizeof returning error on following line
//having trouble seeing how much memory I need
pair *realloc(pair *p, sizeof(pair)+strlen(linestring));
int structPos = 0;
for(i = 0; i<strlen(lineString)-1; i++){
for(int j = 1; j<strlen(lineSTring);j++){
p[structPos]->first = lineString[i];
p[structPos]->last = lineString[j];
structPos++;
}
}
}
}
}
}
else{
printf("pair pointer length is null\n");
}
}
如果有更好的方法,我很樂意改變周圍的情況。 我必須使用上述結構,必須具有結構數組,並且必須使用內存分配。 這些是唯一的限制。
為一個結構數組分配內存就像為一個結構分配內存一樣簡單:
pair *array = malloc(sizeof(pair) * count);
然后,您可以通過訂閱“數組”來訪問每個項目:
array[0] => first item
array[1] => second item
etc
關於realloc部分,而不是:
pair *realloc(pair *p, sizeof(pair)+strlen(linestring));
(這在語法上無效,看起來像是同時分配了realloc函數原型和其調用),應該使用:
p=realloc(p,[new size]);
實際上,您應該使用不同的變量來存儲重新分配的結果,因為在發生內存分配失敗的情況下,它會返回NULL,同時仍保留已分配的內存(然后您將失去其在內存中的位置)。 但是在大多數Unix系統上,當執行臨時處理(不是一些繁重的任務)時,以某種方式到達malloc / realloc返回NULL的情況很少見(您必須耗盡所有虛擬可用內存)。 仍然最好寫:
pair*newp=realloc(p,[new size]);
if(newp != NULL) p=newp;
else { ... last resort error handling, screaming for help ... }
因此,如果我說對了,您在計算的是成對的字符出現了多少次? 為什么當您僅將頻率表保存在64KB數組中時,為什么要使用嵌套循環並使用該對對結構進行更糟的處理呢?這要簡單得多,而且要快幾個數量級。
這大致就是我會做的(警惕:特別是如果這是家庭作業,請不要只是復制/粘貼):
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
void count_frequencies(size_t* freq_tbl, FILE* pFile)
{
int first, second;
first = fgetc(pFile);
while( (second = fgetc(pFile)) != EOF)
{
/* Only consider printable characters */
if(isprint(first) && isprint(second))
++freq_tbl[(first << 8) | second];
/* Proceed to next character */
first = second;
}
}
int main(int argc, char*argv[])
{
size_t* freq_tbl = calloc(1 << 16, sizeof(size_t));;
FILE* pFile;
size_t i;
/* Handle some I/O errors */
if(argc < 2)
{
perror ("No file given");
return EXIT_FAILURE;
}
if(! (pFile = fopen(argv[1],"r")))
{
perror ("Error opening file");
return EXIT_FAILURE;
}
if(feof(pFile))
{
perror ("Empty file");
return EXIT_FAILURE;
}
count_frequencies(freq_tbl, pFile);
/* Print frequencies */
for(i = 0; i <= 0xffff; ++i)
if(freq_tbl[i] > 0)
printf("%c%c : %d\n", (char) (i >> 8), (char) (i & 0xff), freq_tbl[i]);
free(freq_tbl);
return EXIT_SUCCESS;
}
對不起,請注意位操作和十六進制表示法。 我只是碰巧在char表這樣的上下文中喜歡它們,但是為了清楚起見,可以將它們替換為乘法和加法等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.