1

I nead to create a 2d char arry looking like that:

----   
|..|
|..|
----

to do that i wrote a function numed Build_Screen looking like that

#include<stdio.h>
#include"build.h"


void Build_Screen(char **c, int w, int k)
{
    int i=0, j=0;
    for(; i<w;i++)
    {
        j=0;
        for(; j<k;j++)
        {
            if (i==0||i==w-1)
                c[i][j]='-';
            else
            {
                if(j==0||j==k-1)
                    c[i][j]='|';
                else
                    c[i][j]='.';
            }
        }
    }
}

when i tried to run that like that

char screen[5][5];
Build_Screen(screen, 5, 5);

it caused segmentation foult. how do i fix that?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
benjamin
  • 11
  • 1

5 Answers5

2

The problem is that your function taking

char **

is not the same as char[5][5] so just change

void Build_Screen(char **c, int w, int k)

with

void Build_Screen(char c[5][5], int w, int k)

You have to pass the array, not a pointer to char pointer, you can see here, it's explained.

If you don't know the size before hand, then use malloc this way

void Build_Screen(char **c, int w, int k)
{
    int i, j;
    for(i=0;i<w;i++)
    {
        for(j=0;j<k;j++)
        {
            if (i == 0 || i == w-1)
                c[i][j] = '-';
            else
            {
                if(j==0||j==k-1)
                    c[i][j]='|';
                else
                    c[i][j]='.';
            }
        }
    }
}

int main(int argc, char **argv)
{
    char **screen;
    int i, rowCount, columnCount;

    rowCount = 5;
    columnCount = 5;

    screen = malloc(rowCount * sizeof(char *));
    if (screen == NULL)
        return -1;

    for (i = 0 ; i < rowCount ; i++)
    {
        screen[i] = malloc(columnCount);
        if (screen[i] == NULL)
        {
            i -= 1;
            for( ; i >= 0 ; i--)
                free(screen[i]);
            free(screen);
            return -1;
        }
    }
    Build_Screen(screen, rowCount, columnCount);

    /* finished using it */
    for (i = 0 ; i < rowCount ; i++)
        free(screen[i]);
    free(screen);

    return 0;
}

notice that I am assuming that you will print the rows without using printf or similar functions, if you are going to, then just add a terminating '\0' at the end of the strings.

Community
  • 1
  • 1
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
1

A char[5][5] is a 2D array and not a char**. It is a contiguous zone of 25 chars :

00 01 02 03 04 10 11 12 13 14 20 ...

A char ** is a pointer to a pointer to a char :

0  -> 00 01 02 03 04
1  -> 10 11 12 13 14
2  -> 20 ...
3  -> 30 ...
4  -> 40 ...

You must declare it that way :

char ascreen[5][5];
char *screen[5];
for(i=0; i<5; i++) screen[i] = &(ascreen[i][0]);
Build_Screen(screen, 5, 5);

Edit: here is a full program :

#include<stdio.h>

void Build_Screen(char **c, int w, int k)
{
    int i=0, j=0;
    for(; i<w;i++)
    {
        j=0;
        for(; j<k;j++)
        {
            if (i==0||i==w-1)
                c[i][j]='-';
            else
            {
                if(j==0||j==k-1)
                    c[i][j]='|';
                else
                    c[i][j]='.';
            }
        }
    }
}

int main() {
    int i;
    char ascreen[5][5];
    char *screen[5];
    for(i=0; i<5; i++) screen[i] = &(ascreen[i][0]);
    Build_Screen(screen, 5, 5);
    for(i=0; i<5; i++) {
        printf("%.5s\n", screen[i]); /* or printf("%.5s\n", ascreen[i]); */
    }
    return 0;
}

and the output is :

-----
|...|
|...|
|...|
-----
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

Actually, when you state :

char screen[5][5];

What is happening ? It allocates 5*5*sizeof (char) contiguous bytes on the stack, pointed by screen[0]. Thus, screen[0][1] is strictly equivalent to *(screen[0] + 0*5 + 1);

Your problem can be easily resolved by changing your function's signature to

void Build_Screen(char c[5][5], int w, int k);

I guess you want to have a function that works with any size of maps. This won't happen with genuine 2D array in C, except in C99. More details available here.

Community
  • 1
  • 1
Rerito
  • 5,886
  • 21
  • 47
-1

You can also access your array as a one dimensional array. The following code was sucessfully tested locally:

void Build_Screen(char* c, int w, int k)
{
    int i = 0, j = 0;
    for (; i<w; i++)
    {
        j = 0;
        for (; j<k; j++)
        {
            if (i == 0 || i == w - 1)
                c[i*w+j] = '-';
            else
            {
                if (j == 0 || j == k - 1)
                    c[i*w + j] = '|';
                else
                    c[i*w + j] = '.';
            }
        }
    }
}

int main()
{

    char screen[5][5];
    Build_Screen((char*)screen, 5, 5);
}
Andy Reimann
  • 518
  • 4
  • 20
  • I just wanted to say that this is othervise undefined behavior. You only got away with it because you casted to `char*`. – 2501 Dec 18 '14 at 13:42
  • Since the `screen` 2d-array is allocated on stack, it will have contiguous stack memory and thus can be interpreted as a one dimensional array. If it would be dynamically allocated, this might be different. Correct me if I'm wrong. Or what else do you mean by undefined behavior? – Andy Reimann Dec 18 '14 at 13:49
  • 1
    C doesn't define casting to incompatible types. `type(*)[*]` and `type*` are not compatible. `char*` is an exception. – 2501 Dec 18 '14 at 13:50
  • 1
    Indeed, that is something I didn't know and pay attention to. At least learned something out of it about C. Thank you – Andy Reimann Dec 18 '14 at 14:20
  • it doesent work for me. it sais that: worning: assingment makes pointers from integer without a cast[enabled by default] – benjamin Dec 18 '14 at 15:25
-2

As @iharob wrote, your function's signature is not working as you expect. You should use a single pointer char *c and index the array like this or something similar:

c[i+w*j]
Dirk
  • 1,789
  • 2
  • 21
  • 31