[英]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.