Please, I need help for freeing up allocated memory for a really long string. I have tried to trim-down the code to this little piece which encompasses the problem I have:
请,我需要帮助释放分配的内存为一个很长的字符串。我试图将代码缩减到这个包含我遇到的问题的小部分:
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <limits.h>
#define N 6
#define E 1024
int M[N][N][N], R[N*N][N], C[N*N][N], F[N*N][N];
void init_rcf() {
int i, j, k, p;
p = 0;
for(j=0; j<N; j++) {
for(k=0; k<N; k++) {
for(i=0; i<N; i++)
R[p][i] = M[i][j][k];
p++;
}
}
p = 0;
for(i=0; i<N; i++) {
for(k=0; k<N; k++) {
for(j=0; j<N; j++)
C[p][j] = M[i][j][k];
p++;
}
}
p = 0;
for(i=0; i<N; i++) {
for(j=0; j<N; j++) {
for(k=0; k<N; k++)
F[p][k] = M[i][j][k];
p++;
}
}
}
char *bin(int n, int p) {
int c, d, count;
char *pointer;
count = 0;
pointer = (char*)malloc(p+1);
for (c = p-1;c >= 0;c--) {
d = n >> c;
if (d & 1)
*(pointer+count) = 1 + '0';
else
*(pointer+count) = 0 + '0';
count++;
}
*(pointer+count) = '\0';
return pointer;
}
int f0(int n) {
return ceil(log2(n+1));
}
int f1() {
int sum, max = 0;
for(int k=0;k<N;k++) {
for(int j=0;j<N;j++) {
for(int i=0;i<N-1;i++) {
sum = M[i][j][k] + M[i+1][j][k];
if (sum > max)
max = sum;
}
}
}
return max;
}
int f2() {
int sum, max = 0;
for(int k=0;k<N;k++) {
for(int i=0;i<N;i++) {
for(int j=0;j<N-1;j++) {
sum = M[i][j][k] + M[i][j+1][k];
if (sum > max)
max = sum;
}
}
}
return max;
}
int f3() {
int sum, max = 0;
for(int j=0;j<N;j++) {
for(int i=0;i<N;i++) {
for(int k=0;k<N-1;k++) {
sum = M[i][j][k] + M[i][j][k+1];
if (sum > max)
max = sum;
}
}
}
return max;
}
int f4() {
int m1 = f1(), m2 = f2(), m3 = f3();
if ((m1 >= m2) && (m1 >= m3)) return m1;
if ((m1 <= m2) && (m2 >= m3)) return m2;
if ((m1 <= m3) && (m2 <= m3)) return m3;
}
char *g_fxn() {
char *g = (char *) malloc(1 + (N*N*N)*3);
int k = f0(f4());
init_rcf();
strcpy(g,"");
for(int i=0; i<N*N; i++)
for(int j=0; j<N; j++)
strcat(g,bin(R[i][j],k));
for(int i=0; i<N*N; i++)
for(int j=0; j<N; j++)
strcat(g,bin(C[i][j],k));
for(int i=0; i<N*N; i++)
for(int j=0; j<N; j++)
strcat(g,bin(F[i][j],k));
return g;
}
void convert2bin(char *file_in) {
const char *FILENAME_IN = file_in;
const char FILENAME_OUT[] = "temp.txt";
char c, d;
int k=0;
FILE *infile;
FILE *outfile;
infile = fopen(FILENAME_IN, "rb");
outfile = fopen(FILENAME_OUT, "w");
if(infile == NULL){
fprintf(stderr, "Error: Source file not found.\n");
exit(EXIT_FAILURE);
}
while((c = fgetc(infile)) != EOF){
k++;
unsigned n = (sizeof(c) * CHAR_BIT) - 1;
for (int i=0; i<=n; i++) {
int m = (c >> (n-i)) & 1;
d = '0'+m;
fwrite(&d, 1, sizeof(d), outfile);
}
}
if (k < E) {
d = '1';
fwrite(&d, 1, sizeof(d), outfile);
for (int i=k; i<=E; i++) {
d = '0';
fwrite(&d, 1, sizeof(d), outfile);
}
}
fclose(infile);
fclose(outfile);
}
void digest() {
const char *FILENAME_IN = "temp.txt";
const char FILENAME_OUT[] = "digest.txt";
int size = N*N*N; // size of message to construct N*N*N matrix
char c, msg0[size], *msgf;
FILE *infile;
FILE *outfile;
infile = fopen(FILENAME_IN, "r");
outfile = fopen(FILENAME_OUT, "wb");
if(infile == NULL){
fprintf(stderr, "Error: Source file \"temp.txt\" not found.\n");
exit(EXIT_FAILURE);
}
int quit = 0;
while (quit == 0) {
msgf = (char *) malloc(1 + (size)*3);
strcpy(msgf, "");
strcpy(msg0, "");
int p = 0;
while(((c = fgetc(infile)) != EOF) && (p < size)) {
msg0[p++] = c;
}
if(c == EOF) quit = 1;
if (p > 0) {
if (p < size) {
msg0[p] = '1';
for(int i=p+1; i<size; i++)
msg0[i] = '0';
}
for (int k=0; k<N; k++)
for (int j=0; j<N; j++)
for (int i=0; i<N; i++) {
c = msg0[i + N * (j + N * k)];
if (c == '0')
M[i][j][k] = 0;
else
M[i][j][k] = 1;
}
strcpy(msgf, g_fxn());
int q = 0;
while (q<strlen(msgf)) {
int d;
char b = 0;
for (int r=0; r<8; r++) {
if (msgf[q++] == '0')
d = 0;
else
d = 1;
b = ((b<<1) | d);
}
fwrite(&b, 1, 1, outfile);
b = 0;
}
}
}
free(msgf);
fclose(infile);
fclose(outfile);
}
int main(int argc, char *argv[]){
if (argc!=2) {
fprintf(stderr, "Error: Provide name of one source file.\n");
exit(EXIT_FAILURE);
}
char *clear_file = argv[1];
convert2bin(clear_file);
digest();
printf("File successfully digested!\n");
return(0);
}
This code works fine for input files of up to 27 bytes, but beyond that it crashes each time.
此代码适用于最多27个字节的输入文件,但除此之外,它每次都会崩溃。
After trying to debug I discovered the issue lies on the strcpy(msgf, g_fxn());
call to the function g_fxn and my guess is that problem there comes from the big chunk of memory allocated for the message but which seems not to be liberated after. I'm guessing this because the code works when there are less calls to g_fxn but crashes with more calls.
在尝试调试后,我发现问题出在strcpy(msgf,g_fxn());调用函数g_fxn,我的猜测是问题来自为消息分配的大块内存,但似乎没有被解放。我猜这是因为代码可以在对g_fxn的调用较少但有更多调用崩溃的情况下工作。
Anyone has any ideas on how I can fix this?
任何人对我如何解决这个问题都有任何想法?
3 个解决方案
#1
1
msgf gets allocated in the while loop of function digest() a lot of times:
msgf很多次在函数摘要()的while循环中分配:
msgf = (char *) malloc(1 + (size)*3);
But free() is only called once after the loop:
但free()只在循环后调用一次:
free(msgf);
This is at least one memory leak I found.
这至少是我发现的一次内存泄漏。
#2
1
There are functions in which memory is allocated but not freed like in -
有一些函数可以分配内存,但不会释放,如 -
char *g_fxn()
and char *bin(int n, int p)
char * g_fxn()和char * bin(int n,int p)
EDIT
As the pointers are returned in these functions you can use a goto
statement.
在这些函数中返回指针时,您可以使用goto语句。
Well see following example which just shows how to solve your problem -
请看以下示例,它只显示如何解决您的问题 -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char lol(char c[]);
char lol(char c[])
{
char a[6]="hello";
char *p=malloc(sizeof(a));
p=a;
memcpy(c,p,strlen(a));
goto DONE;
DONE:
free(p);
return c;
}
int main()
{
char b[5];
lol(b);
printf("%s",b);
return 0;
}
#3
0
If a function allocates memory and returns the resulting pointer, not freeing the memory, then the calling function has to make sure that it's freed once it's no longer needed. In your strcpy(msgf, g_fxn())
case this could look like this:
如果函数分配内存并返回结果指针,而不是释放内存,则调用函数必须确保在不再需要它时释放它。在你的strcpy(msgf,g_fxn())情况下,这可能如下所示:
char *tmp = g_fxn();
strcpy(msgf, tmp);
free(tmp);
Generally, each time you get a pointer to memory from malloc()
you have to later pass a pointer to that memory to free()
, once it's no longer needed.
通常,每次从malloc()获得指向内存的指针时,必须稍后将指向该内存的指针传递给free(),一旦不再需要它。
#1
1
msgf gets allocated in the while loop of function digest() a lot of times:
msgf很多次在函数摘要()的while循环中分配:
msgf = (char *) malloc(1 + (size)*3);
But free() is only called once after the loop:
但free()只在循环后调用一次:
free(msgf);
This is at least one memory leak I found.
这至少是我发现的一次内存泄漏。
#2
1
There are functions in which memory is allocated but not freed like in -
有一些函数可以分配内存,但不会释放,如 -
char *g_fxn()
and char *bin(int n, int p)
char * g_fxn()和char * bin(int n,int p)
EDIT
As the pointers are returned in these functions you can use a goto
statement.
在这些函数中返回指针时,您可以使用goto语句。
Well see following example which just shows how to solve your problem -
请看以下示例,它只显示如何解决您的问题 -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char lol(char c[]);
char lol(char c[])
{
char a[6]="hello";
char *p=malloc(sizeof(a));
p=a;
memcpy(c,p,strlen(a));
goto DONE;
DONE:
free(p);
return c;
}
int main()
{
char b[5];
lol(b);
printf("%s",b);
return 0;
}
#3
0
If a function allocates memory and returns the resulting pointer, not freeing the memory, then the calling function has to make sure that it's freed once it's no longer needed. In your strcpy(msgf, g_fxn())
case this could look like this:
如果函数分配内存并返回结果指针,而不是释放内存,则调用函数必须确保在不再需要它时释放它。在你的strcpy(msgf,g_fxn())情况下,这可能如下所示:
char *tmp = g_fxn();
strcpy(msgf, tmp);
free(tmp);
Generally, each time you get a pointer to memory from malloc()
you have to later pass a pointer to that memory to free()
, once it's no longer needed.
通常,每次从malloc()获得指向内存的指针时,必须稍后将指向该内存的指针传递给free(),一旦不再需要它。