0

I'm trying to program something for a final project in my C Programming class but I'm stuck on a problem I can't figure out. My code is:

#include <stdio.h>
#include <stdlib.h>
char** allocateLevel(int sizeOfLevel);

int main(void)
{

    char** level = allocateLevel(10);
    int one, two;

    for(one = 0 ; one < 10 ; one++)
    {
        for(two = 0 ; two < 10 ; two++)
        {
            level[one][two]='T'; //Crashes right here

        }
    }
    printf("%c", level[4][5]); //tests to see if it prints
}

char** allocateLevel(int sizeOfLevel)
{
    char **levelPointer;
    levelPointer = (char **)malloc(sizeOfLevel * sizeof(char **));
    int count = 0;


    for(count = 0 ; count < sizeOfLevel ; count++)
    {
        levelPointer[count] = (char*) malloc(sizeOfLevel * sizeof(char*));

    }
}

The program allocates the memory fine but it crashes when I try to assign a value to one of the elements. I can't figure out what's going wrong and my professor hasn't been of much help. Is there anything wrong?

2 Answers2

2

In your function allocateLevel you do not return anything. Hence, the value that ends up as level is pretty much undefined.

  1. Add return levelPointer; at the end of your function allocateLevel.
  2. Enable your compiler warnings. This would have told you "function ends without 'return'."

(Ed.) And what @Oli says -- your sizeofs are both off by a level of indirection.

Jongware
  • 22,200
  • 8
  • 54
  • 100
  • To avoid the malloc size problem, use this idiom, where `p` is your pointer and `N` is how many elements you want: `p = malloc(N * sizeof *p);` – M.M May 01 '14 at 04:45
0

In the line:

levelPointer = (char **)malloc(sizeOfLevel * sizeof(char **));  

There are two issues I can see:
1) You have cast the return of malloc() Good discussion Here
2) sizeof(char **); is addressing dependent (== 8 (64bit), == 4 (32 bit). probably not the result you expected?)

The sizeof operator counts number of bytes of a variable or type. Your usage is giving you results that you are not expecting: run this example:

int main()
{
   cout << "Size of char ** : " << sizeof(char **) << endl;
   cout << "Size of char : " << sizeof(char) << endl;
   cout << "Size of int : " << sizeof(int) << endl;
   cout << "Size of short int : " << sizeof(short int) << endl;
   cout << "Size of long int : " << sizeof(long int) << endl;
   cout << "Size of float : " << sizeof(float) << endl;
   cout << "Size of double : " << sizeof(double) << endl;
   cout << "Size of wchar_t : " << sizeof(wchar_t) << endl;
   return 0;
}  

Often when allocating memory for a char ** the usage is to create an array of strings (which is in turn an array of char). Since you are allocating memory for char ** Take a look at this as an alternative for allocating memory. It provide size parameters, and returns the pointer with memory allocated per the other arguments.

For creating memory

char ** allocMemory(char ** a, int numStrings, int maxStrLen)
{
    int i;
    a = calloc(sizeof(char*)*(numStrings+1), sizeof(char*));
    for(i=0;i<numStrings; i++)
    {
      a[i] = calloc(sizeof(char)*maxStrLen + 1, sizeof(char));
    }
    return a;
}  

For freeing the memory allocated when you are done.

void freeMemory(char ** a, int numStrings)
{
    int i;
    for(i=0;i<numStrings; i++)
        if(a[i]) free(a[i]);
    free(a);
}
Community
  • 1
  • 1
ryyker
  • 22,849
  • 3
  • 43
  • 87