Thread: Help with mallocing a 2d array please?

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    16

    Help with mallocing a 2d array please?

    Hi all,

    Let me preface this with it is a homework assignment I'm working on. It's purpose is to read in pseudo MIPS code and output data hazards.

    The problem I'm having is I'm reading in the file to a 2d char array, and passing it to a function to check the dependencies. But so far I'm having issues with passing the 2d array. I'd originally declared it's size(s) explicitely fileData [20][10], but passing it to the checkDepends function failed to compile as checkDepends was expecting pointers.

    I think the right way to do it is what I have now, declaring fileData as pointers and passing it, but I think I need to malloc fileData, and I've never tried to malloc a 2d array so I don't know what the syntax is. I've googled my butt off, but the examples I found aren't compiling. Here's the code if someone could take a look? The problem I'm having is at the start of the readFile function.

    (I know there's problems in the checkDepends section, I just haven't gotten into it yet to debug it, and I was originally expecting to get the array in a different format, so I'll have to change the indexing in checkDepends)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void readFile(char *mem);
    void checkDepends(char **mips, int lines);
    void printOutput(int fLine, int sLine, char reg, int typeHaz);
    
    char file_name[20];
    int i = 0;
    
    int main(int argc, char *argv[])
    {
    	strcpy(file_name, argv[1]);
    	printf("%s", file_name);
    	readFile(file_name);
    	return 0;
    }
    
    void readFile(char *mem)
    {
    	//declare a pointe of type File.
    	FILE *cfPtr;
    	//declare a character array to store the contents of the lines.
    	char **fileData;
    
    	fileData = malloc(20);
    
    	//declare a positioner to move about the memory array.
    	int linesRead = 0;
    	
    	//point the pointer at the fopen function and test to see if it fails.
    	if((cfPtr = fopen(mem, "r")) == NULL)
    	{
    		//if it does,  tell the user it couldn't open the file.
    		printf("Could not open file");
    		return;
    	}
    
    	//loop through the file,  line by line,  until the end of the file is reached.
    	while(!feof(cfPtr))
    	{
    		//scan each line through the pointer,  store it in the character array.
    		fscanf(cfPtr, "%s", fileData[linesRead]);
    		
    		//increment linesread to the next position in the array.
    		linesRead++;
    	}
    	//confirm the file was read.
    	printf("File read successfully\n");
    	printf("%d\n", linesRead);
    	for(i = 0; i < 40; i++)
    		printf("%c\n", fileData[i][0]);
    	//close the file the pointer is pointing at.
    	fclose(cfPtr);
    
    	linesRead--;
    
    	checkDepends(fileData, linesRead);
    
    }
    
    void checkDepends(char **mips, int lines)
    {
    	int flag = 0;
    	char prevIns[3];
    	char currIns[3];
    	int counter = 1;
    	
    	for(i = 0; i < 3; i++)
    	{	
    		prevIns[i] = mips[i][0];
    	}
    
    	while(counter != lines)
    	{
    		for(i = 0; i < 3;i++)
    		{	
    			currIns[i] = mips[counter][i];
    		}
    		
    		if(strcmp(&prevIns[0], &currIns[1]) == 0 || strcmp(&prevIns[0], &currIns[2]) == 0)
    		{
    			if(strcmp(mips[counter], "lw") == 0)
    			{
    				printOutput((counter - 1 ), counter, prevIns[0], 2);
    			}
    
    			else if (strcmp(mips[counter], "sw") == 0)
    			{
    				printOutput((counter - 1 ), counter, prevIns[0], 2);
    			}
    
    			else if (strcmp(mips[counter], "bne") == 0)
    			{
    				printOutput((counter - 1 ), counter, prevIns[0], 2);
    			}
    
    			else
    			{
    				printOutput((counter - 1 ), counter, prevIns[0], 1);
    			}
    
    			counter++;
    
    			for(i = 0; i < 3; i++)
    				prevIns[i] = currIns[i];
    		}
    	}
    }
    
    void printOutput(int fLine, int sLine, char reg, int typeHaz)
    {
    	switch(typeHaz)
    	{
    		case 1:
    			printf("%d:%d:%s:YES:NO", fLine, sLine, reg);
    		break;
    
    		case 2:
    			printf("%d:%d:%s:YES:YES", fLine, sLine, reg);
    		break;
    
    		case 3:
    			printf("%d:%d:%s:NO:NO", fLine, sLine, reg);
    		break;
    	}
    
    }
    Thanks all in advance for any help you can give!

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    1. Don't use feof() to control a loop (see the FAQ)
    2. fscanf(cfPtr, "&#37;s", fileData[linesRead]); is a serious potential buffer overflow. What if %s is larger than fileData[linesRead]?

    3.
    Code:
    char **fileData;
    fileData = malloc(20);
    Remember we're dealing with char pointers now (ie pointers to pointers to chars). You can however, do:

    Code:
    char * fatArray = malloc(20 * 10);   /* ie, char example[20][10]; */
    Then treat it as an array, or you can do it the old fashion way , allocate room for 20 char pointers, then allocated 10 characters each that the pointers will point to respectively.
    PS: I love MIPS

  3. #3
    Registered User
    Join Date
    Mar 2005
    Posts
    16
    Quote Originally Posted by zacs7 View Post
    1. Don't use feof() to control a loop (see the FAQ)
    2. fscanf(cfPtr, "%s", fileData[linesRead]); is a serious potential buffer overflow. What if %s is larger than fileData[linesRead]?

    3.
    Code:
    char **fileData;
    fileData = malloc(20);
    Remember we're dealing with char pointers now (ie pointers to pointers to chars). You can however, do:

    Code:
    char * fatArray = malloc(20 * 10);   /* ie, char example[20][10]; */
    Then treat it as an array, or you can do it the old fashion way , allocate room for 20 char pointers, then allocated 10 characters each that the pointers will point to respectively.
    PS: I love MIPS
    Ty zacs!

    I actually caught in another thread about feof causing problems, and I did read the faq. I'm not sure I have time to implement it though, and I do know within a range of tolerance what I'll be reading in for this project, so converting it is on my list of things I want to do if I have enough time.

    If you find yourself with a moment, could you tell me what is actually happening behind the scenes with the (20 * 10)? Is it mallocing 20 indexs to sets of 10 indexs? I'm just curious because I don't have a good grasp on malloc unfortunately, I understanding it's allocating a region of memory in the size of the passed parameter, but I'm really fuzzy on how it's handling the 2d arrays. Is this just basically a different syntax to 2d array creation?

    I'm also enjoying MIPS, I originally hated it in my lower(Basic) assembly course when it was really confusing, but now that I'm in upper-level courses it's making sense and I'm finding it's potential interesting. Especially now that I'm learning about data hazards and finding myself wondering if small changes in coding practice can yield significant changes in performance if I think about what happens at low levels with pipelines.

    I swear, once I have some free time on Thanksgiving, I'm writing programs in different ways to see if they yield different performance!

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    20 * 10 = 200. So it's just like calling malloc(200) -- you have 200 characters to play with. How you organize them is up to you -- the compiler isn't going to help. (In other words, no automatic subscripting; array[5][5] won't work.)

    If you want a "real" 2d "array", then you'll have to allocate 20 indexes, and then for each index allocate 10 characters (this is zacs' "old-fashioned" way).

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    char (* fatArray)[10] = (char (*)[10])malloc(20 * 10);
    Malloc just gives you at least the number of bytes you request.
    In C, 2D arrays are just a contiguous chunk of memory the size of [inner dimension] * [outer dimension] * [size of type].
    I think the above code has the correct type.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by Elysia View Post
    Code:
    char (* fatArray)[10] = (char (*)[10])malloc(20 * 10);
    Malloc just gives you at least the number of bytes you request.
    In C, 2D arrays are just a contiguous chunk of memory the size of [inner dimension] * [outer dimension] * [size of type].
    I think the above code has the correct type.
    Had the same question once and I believe the above code is the best way. Dunno if you really understand the code. Just note that :
    Code:
    char (* fatArray)[10]
    is a pointer to an array with 10 char. But
    Code:
    char *fatArray[10]
    is an array of pointers.
    The first has type char (*)[10] and it is ONE pointer.
    The second is an array MANY pointers that have type char*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. from 2D array to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 17
    Last Post: 03-24-2009, 10:33 AM
  2. 2D array becoming "deallocaded"
    By Aaron M in forum C Programming
    Replies: 2
    Last Post: 09-23-2006, 07:53 AM
  3. 2D array pointer?
    By willc0de4food in forum C Programming
    Replies: 4
    Last Post: 04-23-2006, 08:16 AM
  4. Read file in 2D array
    By Chook in forum C Programming
    Replies: 1
    Last Post: 05-08-2005, 12:39 PM
  5. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM