考虑以下抽象代码,从文件中读取一些字节:
typedef struct A{
int size;
char * dataArray;
}A
A load(char* filename, int inSize)
{
A newA;
newA.size = inSize;
FILE *filePtr;
filePtr = fopen(filename,"rb");
char buff[1];
int i = 0;
newA.dataArray = ( char*)malloc(sizeof(char) * newA.size);
for (i = 0; i < newA.size; i++)
{
fread(buff, sizeof(char), 1, filePtr);
newA.dataArray[i] = buff[0];
}
char* copyOfDataArray = (char*)malloc(sizeof(char) * newA.size);
for (i = 0; i < newA.size; i++)
{
fread(buff, sizeof(char), 1, filePtr);
copyOfDataArray[i] = newA.dataArray[i];
}
newA.dataArray = copyOfDataArray;
return newA
}
void Initialize()
{
A first = load("file1", 100);
A second = load("file2", 20);
}
对函数加载的两次调用都返回预期的结果(数据数组与文件具有相同的字节)。第一个和第二个变量永远不会再使用。
然而,在几百行代码之后,程序总是崩溃:
*malloc.c:2451: sYSMALLOC: Assertion '(old_top == (..... failed.*
崩溃总是发生在同一行代码中,但该行与第一个,第二个变量无关,甚至与结构A无关。
我的问题是:我的实例化和加载方式是第一个&#39;和第二个&#39;错误?是否会导致某种内存泄漏/内存溢出,在加载功能完成后很长时间内会导致程序崩溃?
奖金:如果我只加载&#34; file1&#34;,只要加载&#34; file1&#34;就不会发生崩溃。和&#34; file2&#34;崩溃再次出现。
很抱歉这个问题很长。
答案 0 :(得分:1)
那里有内存泄漏。在为此分配新内存之前,必须在newA.dataArray中释放先前分配的内存。
如Joachim所述,读取操作非常耗时,您应该以块的形式读取数据,以最大限度地减少开销。
此外,您必须关闭文件描述符,否则它们很快就会耗尽。
答案 1 :(得分:0)
其他人已经给出了许多代码问题。 请检查下面的
typedef struct A{
int size;
char * dataArray;
}A
A load(char* filename, int inSize)
{
A newA;
newA.size = inSize;
FILE *filePtr = NULL ; //Use NULL
char buff[1]; //Size of buffer is only 1 ,If needed increase that to copy more at a time
int i = 0;
filePtr = fopen(filename,"rb");
//Try to check for the filePtr == NULL or not
newA.dataArray = ( char*)malloc(sizeof(char) * newA.size);
//Same checking should be done here
for (i = 0; i < size; i++) //What is size
{
fread(buff, sizeof(char), 1, filePtr);
newA.dataArray[i] = char[0]; //What is char[0]
}
//instead this you can read the bytes in a single call, use that.
// fread(buff, sizeof(char), <size to read >, filePtr);
char* copyOfDataArray = (char*)malloc(sizeof(char) * newA.size);
for (i = 0; i < size; i++)
{
fread(buff, sizeof(char), 1, filePtr);
copyOfDataArray[i] = newA.dataArray[i];
}
//why reading again once you done above.
newA.dataArray = copyOfDataArray;
return newA; //Please check: How you can return a auto variable.
}
void Initialize()
{
A first = load("file1", 100);
A second = load("file2", 20);
}