【发布时间】:2021-06-09 22:50:33
【问题描述】:
这是我在 stackoverflow 上的第一篇文章。我是一名学习 C 的 CS 学生,我在处理的问题上遇到了一些问题。另外,我应该说我知道的很少,所以如果我放在这里的任何东西被认为是愚蠢或无知的,那绝对不是我的本意
我知道还有其他类似的帖子,但是到目前为止,我觉得我已经尝试了很多修改,都以相同的结果结束。
我得到一个文本文件,其中每一行都包含 studentName(tab)gpa。文件总大小未知,我必须使用动态内存分配。
文本文件格式示例
Jordan 4.0
Bhupesh 2.51
程序的一般步骤
为了让自己免于尴尬,许多细节将被省略,但我将简要概述我正在努力解决的过程:
1.) Create dynamic memory array to hold struct for each line
2.) Start looping through file
3.) check the current size of the array to see if reallocation is necessary
4.) Create dynamic array to hold name
5.) Place name and gpa into struct
6.) rinse & repeat
最后,最后一件事。当达到我的初始分配内存限制并且程序尝试从堆中重新分配更多内存时,就会发生错误。
Screenshot of error being thrown in clion debugger
我的代码如下所示:
#define EXIT_CODE_FAIL 1
#define ROW_COUNT 10
#define BUFFER_SIZE 255
#define VALID_ARG_COUNT 2
struct Student {
float gpa;
char * name;
};
// read the file, pack contents into struct array
struct Student * readFileContents(char *filename, int *rowCounter) {
// setup for loop
int maxDataSize = ROW_COUNT;
float currentStudentGpa = 0;
char studentNameBuffer[BUFFER_SIZE];
// initial structArray pre-loop
struct Student * structArray = calloc(maxDataSize, sizeof(*structArray));
FILE *pFile = fopen(filename, "r");
validateOpenFile(pFile);
// loop through, get contents, of eaach line, place them in struct
while (fscanf(pFile, "%s\t%f", studentNameBuffer, ¤tStudentGpa) > 0) {
structArray = checkArraySizeIncrease(*rowCounter, &maxDataSize, &structArray);
structArray->name = trimStringFromBuffer(studentNameBuffer);
structArray->gpa = currentStudentGpa;
(*rowCounter)++, structArray++;
}
fclose(pFile);
return structArray;
}
// resize array if needed
struct Student * checkArraySizeIncrease(int rowCount, int * maxDataSize, struct Student ** structArray) {
if (rowCount == *maxDataSize) {
*maxDataSize += ROW_COUNT;
**// line below is where the error occurs**
struct Student * newStructArray = realloc(*structArray, *maxDataSize * sizeof(*newStructArray));
validateMalloc(newStructArray);
return newStructArray;
}
return *structArray;
}
// resize string from initial data buffer
char *trimStringFromBuffer(char *dataBuffer) {
char *string = (char *) calloc(strlen(dataBuffer), sizeof(char));
validateMalloc(string);
strcpy(string, dataBuffer);
return string;
}
再次,如果有人问过类似的问题,我深表歉意,但请注意,我已经尝试了我在堆栈溢出中发现的大多数建议,但都没有成功(我很清楚这是我糟糕的编程的结果C)的技能水平。
我现在将立即为我的强制性“stackoverflow 上的第一篇文章”烘焙做好准备。干杯!
【问题讨论】:
-
@paladin Umm,
realloc在大多数情况下都可以正常工作。如果失败,malloc可能也会失败。使用另一个malloc会泄漏内存。 -
如果你增加
structArray,你不能realloc它。您需要在最初分配的内存位置上调用realloc。保持对开头的引用,并增加一个不同的指针。 -
calloc(strlen(dataBuffer), sizeof(char));中的分配缺少 0 终止符,您有可能存在缓冲区溢出 -
@paladin 你真的应该停下来。你认为的灵丹妙药是 realloc 已经做到的。我的印象是,您认为如果
realloc无法扩大当前区域,它将失败。那不是真的。它将简单地执行 malloc、复制、免费,因此没有理由不将realloc用于此处使用的动态数组。 -
欢迎来到 Stack Overflow。您将获得对格式良好且问得很好的问题的投票(将来不会懈怠......)
标签: c struct malloc dynamic-memory-allocation realloc