Click here to Skip to main content
14,982,400 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I have written a c code that finds euclidean distance between corresponding elements of two 2D arrays. i have taken two text files like this..
9.0444 0.083404 -0.30599 -0.21367 -0.032527 -0.048789 -0.17683 -0.10523 0.050547 -0.028377 -0.06061 -0.0011242 -0.031838
9.164 0.18631 -0.3277 -0.1631 -0.014165 -0.041347 -0.063973 -0.059217 0.1422 -0.076865 -0.22507 -0.24214 -0.069154
9.1688 0.27382 -0.21322 -0.21558 -0.20094 -0.2459 -0.21811 -0.22654 -0.093443 -0.14375 -0.17468 -0.17559 -0.079262
8.9909 0.13161 -0.23827 -0.15121 -0.062505 -0.1702 -0.12139 -0.17619 0.035838 -0.089756 -0.17788 -0.089365 0.076777
8.9626 0.006085 -0.20092 -0.21606 -0.010768 -0.089176 -0.12807 -0.073935 0.081079 0.050701 -0.13336 -0.12325 -0.11199

Number of columns are fixed i.e 13 but rows can vary in millions. code is working well with small text files. But it is not working with large text files due to array size. i need to define array dynamically. but i don't know how to do it. This is what i have done so far
C++
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
	int i=0,j,k,x,count=0,n=0,m=13,p=0,q=13;
	float dis=0.0,s=0.0;
	float avg[100],a[100][100],b[100][100];
	//double dis=0,s=0,avg[100];
	char buf[BUFSIZ];
	FILE *fp1,*fp2,*fp3;
	//clrscr();
	fp1=fopen("a1.txt","r");
	fp2=fopen("a2.txt","r");
	//fp3=fopen("ouput.txt","w");
	while (fgets(buf,sizeof(buf),fp1) != NULL)
	n++; // counting rows of a1.txt

	while (fgets(buf,sizeof(buf),fp2) != NULL)
	p++;	// counting rows of a2.txt
	rewind(fp1);

	for(i=0;i<n;i++)
	{
		for(j=0;j<m;j++)
		{
			fscanf(fp1,"%f",&a[i][j]);
			printf("%f ",a[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	rewind(fp2);
	for(i=0;i<p;i++)
	{
		for(j=0;j<q;j++)
		{
			fscanf(fp2,"%f",&b[i][j]);
			printf("%f ",b[i][j]);
		}
		printf("\n");
	}
	      printf("\n");


	//calculation part

	 for(x=0;x<=(n-1);x++)	
	 {
	 if(count!=(n-p)+1){
		i=x;k=0;
		while(i<(p+x))
		{
			for(j=0;j<q;j++)
			{
				s=s+pow((a[i][j]-b[k][j]),2.0);
				dis=sqrt(s);
			}
			i++;
			k++;

		}
		count++;
		avg[i]=dis;
		printf("\n\n%f\n",avg[i]);
	       
		s=0;
	}
	 else
	 break;
	fprintf(fp3,"%f\n",avg[i]);
	   
 }
	//getch();
	fclose(fp1);
	fclose(fp2);
	fclose(fp3);
}

Any help is appriciated...Thank you.
Posted
Updated 20-Aug-13 1:51am
v4

change:
C++
float avg[100],a[100][100],b[100][100];


with
C++
float * avg;
float ** a;
float ** b;


and, once both n and p have been computed, dynamically allocate memory, namely:

C++
avg = (float *) malloc(n* sizeof(float));
a = (float**) malloc(n * sizeof(float *));
b = (float**) malloc(p * sizeof(float *));

for (i=0; i<n; i++)
  a[i] = (float *) malloc(13 * sizeof(float);

for (i=0; i<p; i++)
  b[i] = (float *) malloc(13 * sizeof(float);

eventually use the arrays exactly like you did before.

Please note:
  • Don't forget to release memory (calling free).
  • It would be better if you could swap indices on the bidimensional array, that is having a[13][n] instead of a[n][13].
   
Comments
pasztorpisti 20-Aug-13 10:07am
   
5ed. I've came up with a poor man's allocation solution that does the job in case of simple programs, please see. :-)
CPallini 20-Aug-13 11:14am
   
Thank you.
Joezer BH 20-Aug-13 10:15am
   
5ed!
CPallini 20-Aug-13 11:14am
   
Thank you.
Member 10220440 22-Aug-13 3:03am
   
I made the changes asked for. But this time i reduced my code for only reading and writing files. when I executed the code, it is still not able to read whole 1.txt file, and printing some garbage values in output2.txt.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void main()
{
int i=0,j,n=0,p=0,m=13,q=13;
float **a;
float **b;
char buf[BUFSIZ];
FILE *fp1,*fp2,*fp3,*fp4;
clrscr();
fp1=fopen("1.txt","r");
fp2=fopen("2.txt","r");
fp3=fopen("output1.txt","w");
fp4=fopen("output2.txt","w");
while (fgets(buf,sizeof(buf),fp1) != NULL)
n++; // counting rows of a1.txt

while (fgets(buf,sizeof(buf),fp2) != NULL)
p++; // counting rows of a2.txt
rewind(fp1);

for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
a = (float**) malloc(n * m * sizeof(float *));
fscanf(fp1,"%f",&a[i][j]);
fprintf(fp3,"%f ",a[i][j]);
}
printf("\n");
}
printf("\n");
rewind(fp2);
for(i=0;i<p;i++)
{
for(j=0;j<q;j++)
{
b = (float**) malloc(p * q * sizeof(float *));
fscanf(fp2,"%f",&b[i][j]);
fprintf(fp4,"%f ",b[i][j]);
}
printf("\n");
}
printf("\n");
getch();
fclose(fp1);
fclose(fp2);
fclose(fp3);
fclose(fp4);
free(a);
free(b);
}


do't know what mistake I am doing....
Member 10220440 22-Aug-13 5:31am
   
Thank you...It is working now. :)
CPallini 22-Aug-13 5:33am
   
You are welcome.
Since you declared your arrays as local variables of a function these array are allocated from the stack space of the Main thread of your program and stack space is usually limited to a few megabytes/thread on most popular OSes for several reasons. You can overcome this limitation by declaring your array either as static inside your function, or by putting these arrays out from the main function (to global scope): this way the arrays automatically become "static" and they don't take stack space.

This way you sacrifice thread safety of your function that isn't an issue because your program isn't multithreaded but you made your code easier to read then with a few ugly mallocs by letting the OS allocate the space for you. If you declare your large arrays without initialization then this doesn't increase the size of your executable.

Of course this allocation isn't dynamic, its fixed size but the size is limited only by the available memory in your system. In smaller test/"script" programs I often prefer using this simple "barbar" solution to ask the OS to allocate memory for me. :-)
   
v3
Comments
CPallini 20-Aug-13 11:14am
   
My 5.
pasztorpisti 20-Aug-13 11:37am
   
Thank you!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900