writing to a multidimensional array in c

Discussion in 'Mac Programming' started by farmerdoug, Jan 9, 2010.

  1. farmerdoug macrumors 6502a

    Joined:
    Sep 16, 2008
    #1
    I declare an array and create memory for it.

    Code:
    	char ****averages4;//[1500][5][45][8];
    for( i = 0; i <1500; i++)
    	{
    	if ((averages4[i] = (char ***) calloc(5, sizeof(char**))) == NULL)
    		{
    		printf("no memory");
    		return(0);
    		}
    		   for( j = 0; j < 5; j++)
    		  {
    		if ((averages4[i][j] = (char **) calloc(45, sizeof(char*))) == NULL)
    		{
    				printf("no memory");
    				return(0);
    			}
    			
    			for( k = 0; k < 45; k++)
    			{
    				if ((averages4[i][j][k] = (char *) calloc(8, sizeof(char))) == NULL)
    				{
    					printf("no memory");
    					return(0);
    				}
    			}
    		}
    	}
    
    I declare an array and create memory for it.
    Code:
    char ****averages4;//[1500][5][45][8];
    for( i = 0; i <1500; i++)
    {
    if ((averages4[i] = (char ***) calloc(5, sizeof(char**))) == NULL)
    {
    printf("no memory");
    return(0);
    }
    for( j = 0; j < 5; j++)
    {
    if ((averages4[i][j] = (char **) calloc(45, sizeof(char*))) == NULL)
    {
    printf("no memory");
    return(0);
    }
    
    for( k = 0; k < 45; k++)
    {
    if ((averages4[i][j][k] = (char *) calloc(8, sizeof(char))) == NULL)
    {
    printf("no memory");
    return(0);
    }
    }
    }
    } 
    
    The send it to a function void readdata( char ****averages4 ...
    but when I try to right to it ( or at least read from it) I can only access the zeroth row on each page.
    strcpy(averages4[*i4][1][5],arr[18]); does not work or
    printf("%s \n", averages4[*i4][1][5]);
    does not print a value. printf("%s \n", averages4[*i4][0][5]); does.
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    In the future, please post your code in [CODE][/CODE] tags. Also, include a complete, compilable example, not a segment that someone has to stick in a function, declare variables, etc.

    Give this a try:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void func(char ****arr);
    
    int main(int argc, char *argv[]) {
      char ***averages4[1500];//[1500][5][45][8];
      int i,j,k;
      for( i = 0; i <1500; i++) {
        if ((averages4[i] = (char ***) calloc(5, sizeof(char**))) == NULL) {
          printf("no memory");
          return(0);
        }
        for( j = 0; j < 5; j++) {
          if ((averages4[i][j] = (char **) calloc(45, sizeof(char*))) == NULL) {
            printf("no memory");
            return(0);
          }
          for( k = 0; k < 45; k++) {
            if ((averages4[i][j][k] = (char *) calloc(8, sizeof(char))) == NULL) {
              printf("no memory");
              return(0);
            }
          }
        }
      } 
      func(averages4);
      for(i=0;i<1500;i++) {
        for(j=0;j<5;j++) {
          for(k=0;k<45;k++) {
            printf("averages4[%d][%d][%d] = %s\n",i,j,k,averages4[i][j][k]);
            free(averages4[i][j][k]);
          }
          free(averages4[i][j]);
        }
        free(averages4[i]);
      }
    }
    
    void func(char ****arr) {
      int w,x,y;
      for(w = 0;w<1500;w++) {
        for(x = 0;x<5;x++) {
          for(y = 0;y<45;y++) {
            sprintf(arr[w][x][y],"%d",(w*x*y)%10000000);
          }
        }
      }
    }
    
    If you want to dynamically allocate the primary dimension as well, you can. You'd need to calloc(1500,sizeof(char ***)) outside of your loops.

    -Lee

    EDIT: The mod is probably unnecessary now that i look at the math, but it was done to ensure an overflow does not occur.
     
  3. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #3
    writing to a multidimensional array in c

    I used to know where to find instructions for the code tags. Please send a link and I'll sent the whole code.

    Meanwhile, it works better. However despite allocating memory, I get a segmentation error when *i4 reaches 456; I get the same error if I comment out all the sprintf statements but the error occurs at 1256 even though there are no other calls to averages. 1500 pages are reserved for averages4.
    {
    sprintf(averages4[*i4][0][0],"%s", arr[1]);
    sprintf(averages4[*i4][0][1],"%s", arr[6]);
    sprintf(averages4[*i4][0][2],"%s", arr[5]);
    sprintf(averages4[*i4][0][3],"%s", arr[8]);
    sprintf(averages4[*i4][1][*m],"%s", arr[18]);
    sprintf(averages4[*i4][2][*m],"%s", arr[22]);
    sprintf(averages4[*i4][3][*m],"%s", arr[83]);
    printf("%d %s %s\n",(*i4)++, arr[8], arr[5]);
    }
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    There's no link that I'm aware of, just put your code inside tags like the ones I posted in my last message. You can press the button with the hash mark on it to insert them, too. Please post all of your code, because without context it is impossible to tell what is going wrong.

    -Lee
     
  5. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #5
    writing to a multidimensional array in c code

    Code:
    void readdata( char ****averages4 ,char ****averages5, FILE * fp, int *i4, int *i5, int *m )
    	{
    		
    		FILE * action;
    		char *listname, *line, *tmp;
    		char **arr; 
    		int fldcnt=0;
    		int j, n, k;
    		int oldfound,value, notzero;
    		i4 = (int *) calloc(1, sizeof(int));
    		i5 = (int *) calloc(1, sizeof(int));
    		m = (int *) calloc(1, sizeof(int));
    		listname = (char*)calloc(50, sizeof(char));
    		tmp = (char*)calloc(1024, sizeof(char));
    		line = (char*)calloc(1024, sizeof(char));
    		arr = (char **)calloc(100, sizeof(char*));
    		for(j = 0; j < 100; j++)
    			arr[j] = (char *)calloc(10,sizeof(char));
    		*i4 = 0;
    		*i5 = 0;
    		*m = 0;
    		fscanf(fp, "%s\n", listname); //get first file
    		action = fopen(listname, "r"); //open first file
    		fscanf(action, "%s\n", line); // discard first lineprintf("%s\n",  arr[i]);
    		
    	//	printf("%ld\n", sizeof((char*)tmp));
    		printf("%s\n", listname);
    		while (fgets(tmp,1024,action) != 0)
    		{
    	//	fgets(tmp,1024,action);
    	//	{
    			parse(tmp,",",(char**)arr,&fldcnt); // whack record into fields 
    			//printf("here\n");
    			//printf("%s %s %s %s %s\n", arr[2],arr[5],arr[7],arr[8],arr[9]);
    			if ( (atoi(arr[2]) == 1) && (atoi(arr[5]) > 20 ) &&( (atoi(arr[7]) == 4) || (atoi(arr[7]) == 5)) && (atoi(arr[8]) < 30) && ( (strcmp(arr[9], "Non-Leap") == 0)))
    				if(atoi(arr[7]) == 5)
    				{	
    					sprintf(averages4[*i4][0][0],"%s", arr[1]);
    					sprintf(averages4[*i4][0][1],"%s", arr[6]);
    					sprintf(averages4[*i4][0][2],"%s", arr[5]);
    					sprintf(averages4[*i4][0][3],"%s", arr[8]);
    					sprintf(averages4[*i4][1][*m],"%s", arr[18]);
    					sprintf(averages4[*i4][2][*m],"%s", arr[22]);
    					sprintf(averages4[*i4][3][*m],"%s", arr[83]); 
    					(*i4)++;
    		//			printf("%s %s\n",(char*) averages4[*i4][0][0],arr[1]);	
    					
    					}
    				else 
    				{				
    		/*			strcpy(averages5[*i5][0][0],arr[1]);
    					strcpy(averages5[*i5][0][1],arr[6]);
    					strcpy(averages5[*i5][0][2],arr[5]);
    					strcpy(averages5[*i5][0][3],arr[8]);
    					strcpy(averages5[*i5][1][*m],arr[18]);
    					strcpy(averages5[*i5][2][*m],arr[22]);
    					strcpy(averages5[(*i5)++][3][*m],arr[83]);
    		*/			}
    		}	
    	//
    		fclose(action);	
    	
    		
    		//	for(j = 0; j < 15; j++) 
    		//	printf(" %s\n", averages4[j - 1][3][4]);	
    		
    		
    				// do rest of files
    	while ( (fscanf(fp, "%s\n", listname)) == 1)
    {
    			//for(*i4 = 0; *i4 < 15; *i4++) 
    			//	printf(" %s\n", averages4[*i4 - 1][3][4]);
    			printf("%d %s \n",*m,  listname);
    
    			*m += 1;
    		
    			action = fopen(listname, "r"); //open next file
    			
    			
    
    			fscanf(action, "%s\n", line); // discard first lineprintf("%s\n",  arr[i]);
    			
    		while (fgets(tmp,1024,action) != 0)
    		{
    				parse(tmp,",", (char**) arr,&fldcnt); // whack record into fields 
    			
    				
    				//	printf("%s \n", arr[2]);
    		if ( (atoi(arr[2]) == 1) && (atoi(arr[5]) > 20 ) && ( (atoi(arr[7]) == 4) || (atoi(arr[7]) == 5)) && (atoi(arr[8]) < 30) && ( (strcmp(arr[9], "Non-Leap") == 0)))
    			{					
    					oldfound = 0;
    					for (j = 0; j < *i4 + *i5; j++)
    					{// printf("%d\n", j);
    						if  (atoi(arr[7]) == 4)
    							if ( ( (strcmp(averages4[j][0][0],arr[1]) == 0)  &&  (strcmp(averages4[j][0][1],arr[6]) == 0)  && (strcmp(averages4[j][0][2],arr[5]) == 0)) )
    									{ 
    								
    								oldfound = 1;
    								notzero = 1;
    								n = *m - 1;
    								while (notzero == 1)
    									if ( atoi(averages4[j][1][n]) != 0)
    									{
    										value = atoi(averages4[j][1][n]) + atoi(arr[18]);
    										sprintf(arr[18],"%d", value);
    										sprintf(averages4[j][1][*m],"%s",arr[18]);
    										
    										value = atoi(averages4[j][2][n]) + atoi(arr[22]);
    										sprintf(arr[22],"%d", value);
    										sprintf(averages4[j][2][*m],"%s",arr[22]);
    										
    										value = atoi(averages4[j][3][n]) + atoi(arr[83]);
    										sprintf(arr[83],"%d", value);
    										sprintf(averages4[j][3][*m],"%s", arr[83]); 
    										notzero = 0;
    										//	printf("%d\n", *m);
    									
    									}
    									else
    										n--;
    								
    								j = 100000;	
    							}  //end if 4
    						if  (atoi(arr[7]) == 5)
    							if ( ( (strcmp(averages5[j][0][0],arr[1]) == 0)  &&  (strcmp(averages5[j][0][1],arr[6]) == 0)  && (strcmp(averages5[j][0][2],arr[5]) == 0)) )
    									{
    								
    								oldfound = 1;
    								notzero = 1;
    								n = *m - 1;
    								while (notzero == 1)
    									if ( atoi(averages5[j][1][n]) != 0)
    									{
    						/*				value = atoi(averages5[j][1][n]) + atoi(arr[18]);
    										sprintf(arr[18],"%d", value);
    										strcpy(averages5[j][1][*m],arr[18]);
    										
    										value = atoi(averages5[j][2][n]) + atoi(arr[22]);
    										sprintf(arr[22],"%d", value);
    										strcpy(averages5[j][2][*m],arr[22]);
    										
    										value = atoi(averages5[j][3][n]) + atoi(arr[83]);
    										sprintf(arr[83],"%d", value);
    										strcpy(averages5[j][3][*m],arr[83]); 
    										notzero = 0;
    										
    						*/						//		printf("%d\n", *m);	
    									}
    								
    									else
    										n--;
    								
    								j = 100000;	
    							}  // end if 5
    					} 
    					if (oldfound == 0)
    							{//printf("%d %s \n",*m,  arr[83]);
    							if(atoi(arr[7]) == 4)
    								{ //FAILS HERE
    								sprintf(averages4[*i4][0][0],"%s", arr[1]);
    								sprintf(averages4[*i4][0][1],"%s", arr[6]);
    								sprintf(averages4[*i4][0][2],"%s", arr[5]);
    								sprintf(averages4[*i4][0][3],"%s", arr[8]);
    								sprintf(averages4[*i4][1][*m],"%s", arr[18]);
    								sprintf(averages4[*i4][2][*m],"%s", arr[22]);
    								sprintf(averages4[*i4][3][*m],"%s", arr[83]); 
    									printf("%d %s %s\n",(*i4)++, arr[8], arr[5]);	
    								}
    								else 
    								{
    					/*			strcpy(averages5[*i5][0][0],arr[1]);
    								strcpy(averages5[*i5][0][1],arr[6]);
    								strcpy(averages5[*i5][0][2],arr[5]);
    								strcpy(averages5[*i5][0][3],arr[8]);
    								strcpy(averages5[*i5][1][*m],arr[18]);
    								strcpy(averages5[*i5][2][*m],arr[22]);
    								strcpy(averages5[(*i5)++][3][*m],arr[83]); 
    					*/			}
    							}///end if oldfound
    				
    			 }	// end if
    		
    				
    			} //end of while (fgets)
    			fclose(action);	
    		}  //end while do restv
    				
    		for(k = 0; k < 15; k++) 
    			printf("%s %s\n", averages4[k][0][0],averages4[k][2][3] );			
    		free(i4);
    		free(i5);
    		free(m);
    	}
    
    
     
  6. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #6
    There's no main function here, and there's not a parse function that i know of that's built-in. It also appears that there are a lot of items, i.e. i4, that are passed in as a pointer, then assigned a new address. This won't change the pointer in the caller, but it's pretty much equivalent to declaring a local variable. This seems unnecessary

    If you can post the definitions of the other functions, it may be easier to test this and find the problem. It also might be helpful to post what you're trying to do. Also, please post the text files you're using, since this requires external data to run.

    -Lee

    EDIT: I'm reading this code and trying to make heads or tails from it. Still working through it, but right off the bat there is a lot that is calloc'd that is never free'd, so every call to this function will leak memory.

    EDIT 2:
    1) You can use strcpy(x,y) instead of sprintf(x,"%s",y)
    2) When you want to get out of a loop, use break;. Don't try to game your loop control variable.
    3) At one point there is a while(notzero == 1) loop. There is a possibility that a nonzero value will never be found. If this is the case, n will become negative. when it does you will underflow the array, and could get erratic behavior or a crash.
    4) i5 is never changed, it seems like it can just be removed.
    5) Unless you suspect that a lot of the stack will already be used, you don't need to dynamically allocate anything in this function. 3KB or so on the stack shouldn't be an issue at all. Putting it on the heap doesn't seem to be worth the trouble, especially since you didn't take care of free'ing everything properly.

    Without the rest of the code and the data files, i can't really figure out the rest. It may be something that straight code analysis could decipher, but it would be much easier to be able to run it to find the problem.
     
  7. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #7
    writing to a multidimensional array in c

    I think I am obligated not to send out the full code and the data. In addition, having further narrowed the source of the problem, I think that while it may have taken you less time than it has taken me, I don't think you would have want to invest the time.

    Always grateful
    doug
     

Share This Page